急于加载和使用'where'方法的麻烦

时间:2012-03-09 04:42:51

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1 eager-loading

我正在运行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语句取消了预先加载的效果。

1 个答案:

答案 0 :(得分:3)

在案例1中,where子句仅适用于类别。如果您还希望它适用于评论,您可以这样做:

article_categories =
  article
    .categories
    .includes(:comments)
    .where('categories.user_id = ? AND comments.user_id = ?', @current_user.id, @current_user.id)