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

我正在运行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查询问题”。 但是,上面的代码还返回没有: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查询问题”…但注释有“ :user_id == @current_user.id ”!

我想用“ :user_id == @current_user.id ”来加载注释( 如何利用热切的加载来实现这一点? )我想了解为什么where语句取消了预期的加载效果。

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

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