読者です 読者をやめる 読者になる 読者になる

kmasdaの日記

rubyとかrailsとかそれっぽいことを

N+1はEager loadingで回避

rails

担当してるプロジェクトのlogにN+1が発生してておやおやってなったので修正した

Eager Loading

Active Record Query Interface — Ruby on Rails Guides

一括でデータをロードしておくことで参照の都度SQLが発行されるのを防ぐ。

where!

今回の修正はcontroller側でこんな感じに修正してた。

def index
   @posts =   if params[:foo]
     Post.where(foo: params[:foo]).includes(:user)
    else
     Post.all.includes(:user)
  end
end

師匠から、

  • .allはnoopなのでいらない。
  • .include(:users)がこの短いメソッドで2回も出てくる(=DRYじゃない)
  • (あんまり好きじゃないけど、)where!を使うと既存のRelationを破壊的に操作できてすっきり書ける。

とアドバイスをもらいました。 最終的に

def index
  @posts = Post.includes(:user)
  @posts = Post.where!(foo: params[:foo]) if params[:foo]
end

すっきり綺麗にかけた。