在诊断N + 1查询问题时,我注意到ActiveRecord has_one / has_many:链接在一起时通过关联忽略包含。
示例代码(我的案例与我们的模型一致):
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
进行另一次LIMIT 1查询。这将导致循环中的N + 1。
为了解决这个问题,我想用代理来替换所有的has_one / many:through。 has_many / one:through选项是否有任何优势(对于没有条件的情况)?
答案 0 :(得分:1)
我认为此代码可能对您有用。
post = Post.includes(:user => [:badge])
答案 1 :(得分:1)
问题很可能包括(:user =&gt;:badge)遵循Post.user关联,然后是User.badge关联,所以当你遵循单个Post.badge关联时,Rails会忽略包含,因为你'为不同的协会设置了它。
即使它们是相同的路径,它们也是不同的关联。
只是包括(:徽章)会更好。