我正在运行Ruby on Rails 3.1。我正在使用includes
方法,我想了解为什么当我在一个急切加载的集合上调用where
方法时,它会重新加载关联的对象,而不是仅仅在eager加载的集合中找到该对象。由于所有相关对象都已被急切加载,我希望where
方法不命中数据库以重新加载这些对象!
也就是说,我有以下内容:
article_categories =
article
.categories
.where(:user_id => @current_user.id)
.includes(:comments)
如果我跑
# CASE 1:
article_categories.each do |article_category|
article_category.comments.map(&:title)
end
急切加载按预期工作:避免了“N + 1查询问题”。但是,上面的代码还会返回 not “:user_id == @current_user.id
”的评论标题,但我根本不想检索这些标题。
所以,因为我认为通过使用热切加载我已经得到了所有注释,我使用了另外的where(:user_id => @current_user.id)
语句,如下面的代码所示:
# CASE 2:
article_categories.each do |article_category|
article_category.comments.where(:user_id => @current_user.id).map(&:title)
end
但是,在这种情况下,急切加载不按预期工作:“N + 1查询问题”不避免...但评论有“{{ 1}}!“
我想热切地用“:user_id == @current_user.id
”加载评论(如何利用热切的加载来实现这一点?)我想了解为什么:user_id == @current_user.id
语句取消了预先加载的效果。
答案 0 :(得分:3)
在案例1中,where子句仅适用于类别。如果您还希望它适用于评论,您可以这样做:
article_categories =
article
.categories
.includes(:comments)
.where('categories.user_id = ? AND comments.user_id = ?', @current_user.id, @current_user.id)