Rails 7.2: ActiveRecord::Base#pluckにハッシュ値を渡せるようになった(翻訳)
グラフやレポートで構成されたダッシュボードを目にすることは普段からよくあります。このようなグラフやレポートを素早く作成するには、さまざまなデータベーステーブルから特定のデータを取得するクエリを高速化する必要があります。
ActiveRecord::Base#pluck
メソッドは、レコード全体を読み込まずに、データベースから1個以上の属性をクエリするのに使われます。pluck
の結果は属性値の配列として返されます。
User.pluck(:id, :name, :email)
上のコードから以下のクエリが生成されます。
SELECT users.id, users.name, users.email FROM "users"
上のクエリの結果から以下の配列を得られます。
#=>
[
[1, "David Heinemeier Hansson", "dhh@hey.com"],
[2, "Rafael França", "rafael@franca.dev"],
[3, "Vipul Amler", "vipul@saeloun.com"]
]
🔗 改修前
クエリでフィールドを取得するときは、単一のテーブルからの取得に限定されず、複数テーブルからも取得できます。
カラム名はシンボル形式で指定可能ですが、従来は単一のテーブルからカラムをフェッチするときしかシンボル指定を利用できません。
複数テーブルをJOINしたい場合は、テーブル名を指定するために以前の文字列形式を使わなければなりませんでした。
Raila 7.2より前は、以下の構文で特定のフィールドをフェッチできました。
Employee
.joins(:companies)
.pluck("employees.id, employees.name, companies.id, companies.name")
上のコードから以下のクエリが生成されます。
SELECT employees.id, employees.name, companies.id, companies.name
FROM "employees"
INNER JOIN "companies"
ON companies.id = employees.company_id
上のクエリの結果から以下の配列が得られます。
#=>
[
[1, "David Heinemeier Hansson", 1, "37signals"],
[2, "Jason Fried", 1, "37signals"],
[3, "Rafael França", 2, "Shopify"],
[4, "Vipul Amler", 3, "Saeloun"]
]
🔗 改修後
Rails 7.2から、ActiveRecord::Base#pluck
にハッシュ値を渡せるようになりました(#51565)。これにより、生SQLを使わずに同じクエリが可能になりました。
改修後の同じコードを見てみましょう。
Employee
.joins(:companies)
.pluck(employees: [:id, :name], companies: [:id, :name])
上のコードから以下のクエリが生成されます。
SELECT employees.id, employees.name, companies.id, companies.name
FROM "employees"
INNER JOIN "companies"
ON companies.id = employees.company_id
pluck
を用いて実装されているpick
メソッドにも同じことが適用されます。
pick
メソッドは、relation.limit(1).pluck(*column_names).first
のショートハンドであり、リレーションが既に1行にまで絞り込まれている場合に便利です。
Employee
.joins(:companies)
.where(id: 1)
.pick(employees: [:id, :name], companies: [:id, :name])
上のコードから以下のクエリが生成されます。
SELECT employees.id, employees.name, companies.id, companies.name
FROM "employees"
INNER JOIN "companies"
ON companies.id = employees.company_id
WHERE employees.id = 1
LIMIT 1
上のクエリの結果から以下の配列が得られます。
#=>
[1, "David Heinemeier Hansson", 1, "37signals"]
なお、以下の過去記事で既に取り上げたように、select
とreselect
にも同様にハッシュ値を渡せます。
- ActiveRecord::QueryMethods#select adds support for hash values in Rails 7.1 | Saeloun Blog
- Rails 7.1 Allows ActiveRecord reselect Query Method To Accept Hash | Saeloun Blog
概要
元サイトの許諾を得て翻訳・公開いたします。