2

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オプション(条件がない場合)に利点はありますか?

4

2 に答える 2

1

このコードの方がうまくいくと思います。

post = Post.includes(:user => [:badge])
于 2012-08-30T02:51:31.380 に答える
1

include(:user =>:badge)がPost.userアソシエーション、次にUser.badgeアソシエーションに従うという問題が発生する可能性があります。したがって、単一のPost.badgeアソシエーションに従うと、Railsはインクルードを設定してから無視します。さまざまな協会のために。

つまり、同じパスであっても、それらは異なる関連付けです。

include(:badge)だけの方がうまくいくでしょう。

于 2012-08-30T03:00:07.207 に答える