LoginSignup
6

More than 5 years have passed since last update.

ViewでのpluckメソッドはN+1を引き起こす可能性があるので気をつける

Posted at

具体例

例えば、CustomerテーブルとTelephoneテーブルがあり1つのCustomerがN個Telephoneテーブルを持つとする。
Customer一覧でそのCustomerが持ってる全てのTelephoneのtelカラムを一覧でカンマ区切りで表示したい場面があった時に

customers_controller.rb
def index
  @customers = Customer.includes(:telephones)
end
customers/index.html.slim
- @customers.each do |customer|
  = customer.telephones.pluck(:tel).join(', ')

とすると、コントローラーでincludesしてeager loadingしているにも関わらずN+1になる。

原因

pluckメソッドがSQLのselect文を発行するため。
そのため、Viewでループでcustomerのtelを参照するたびにselect文が発行されてN+1のクエリになります。

対策

pluck(:tel)map(&:tel) に変える。それにより、本来の事前にロードされたtelephonesのtelを見るようになるため N+1を回避できます。

しっかりpluckメソッドの動きを把握すればハマらない問題でした。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6