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

进行另一个 LIMIT 1 查询。这将导致 N+1 在循环中。

为了解决这个问题,我想用代表替换所有 has_one/many :through。has_many/one :through 选项有什么优势(在没有条件的情况下)?

4

2 回答 2

1

问题很可能是 include(:user => :badge) 遵循 Post.user 关联,然后是 User.badge 关联,因此当您遵循单个 Post.badge 关联时,Rails 会忽略包含,因为您已经设置了它对于不同的协会。

也就是说,即使它是相同的路径,它们也是不同的关联。

只包括(:徽章)会更好。

于 2012-08-30T03:00:07.207 回答
1

我认为这段代码可能更适合你。

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