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

时间:2022-10-05 14:45:07

I am running Ruby on Rails 3.1. I am using the includes method and I would like to understand why when I call the where method on an eager loaded collection it reloads associated objects instead of just finding that object in the eager loaded collection. Since all related objects are already been eager loaded I expect that the where method does not hit the database to reload those objects!

我正在运行Ruby on Rails 3.1。我正在使用includes方法,我想了解为什么当我在一个渴望加载的集合上调用where方法时,它会重新加载关联的对象,而不是仅仅在eager加载的集合中找到该对象。由于所有相关对象都已被急切加载,我希望where方法不会命中数据库来重新加载这些对象!

That is, I have the following:

也就是说,我有以下几点:

article_categories =
  article
    .categories
    .where(:user_id => @current_user.id)
    .includes(:comments)

If I run

如果我跑

# CASE 1:

article_categories.each do |article_category|
  article_category.comments.map(&:title)
end

eager loading works as expected: the "N + 1 query problem" is avoided. However, the above code returns also comment titles that have not ":user_id == @current_user.id", but I do not want to retrieve those ones at all.

急切加载按预期工作:避免了“N + 1查询问题”。但是,上面的代码还返回没有“:user_id == @ current_user.id”的注释标题,但我根本不想检索那些。

So, since I thought that by using the eager loading I already get all comments, I used a further where(:user_id => @current_user.id) statement like in the following code:

所以,因为我认为通过使用热切加载我已经获得所有注释,我使用了另外的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

However, in this case eager loading does not work as expected: the "N + 1 query problem" is not avoided... but comments have ":user_id == @current_user.id"!

但是,在这种情况下,急切加载不能按预期工作:不能避免“N + 1查询问题”...但注释有“:user_id == @ current_user.id”!

I would like to eager loading comments with ":user_id == @current_user.id" (how can I make that by taking advantage from the eager loading?) and I would like to understand why the where statement cancels eager loading effects.

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

1 个解决方案

#1


3  

In case 1 the where clause only applies to categories. If you also want it to apply to comments you can do this:

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

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

#1


3  

In case 1 the where clause only applies to categories. If you also want it to apply to comments you can do this:

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

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