N + 1クエリの問題を診断しているときに、ActiveRecord has_one / has_many:throughアソシエーションがチェーンされている場合、インクルードを無視していることに気付きました。
サンプルコード(私の場合はモデルを使用していました):
class Post < ActiveRecord::Base
has_one :user
has_one :badge, through: :user
end
class User < ActiveRecord::Base
has_one :badge
end
class Badge < ActiveRecord::Base
end
アソシエーションを通過しても、インクルード以外の追加のクエリは実行されません
post = Post.include(:user => :badge)
post.user.badge
しかし、スルーを使用しようとしています:
post = Post.include(:user => :badge)
post.badge
別のLIMIT1クエリを作成します。その結果、ループ内でN+1になります。
これを解決するために、すべてのhas_one / many:throughをデリゲートに置き換えることを考えました。has_many / one:throughオプション(条件がない場合)に利点はありますか?