ActiveRecord:不能在具有急切加载关联的`where` 子句之后使用`pluck` [英] ActiveRecord: can't use `pluck` after `where` clause with eager-loaded associations
问题描述
我有一个应用程序,它有多个 Post
模型,每个模型 belongs_to
一个 User
模型.发布这些帖子后,会创建一个 PublishedPost
模型,该模型belongs_to
相关的 Post
模型.
我正在尝试构建一个 ActiveRecord 查询来查找与用户名匹配的已发布帖子,然后获取这些已发布帖子的 ID,但是当我尝试使用 pluck
方法在预先加载我的关联并使用 where
方法搜索它们之后.
这是我的控制器的(部分):
class PublishedPostsController <应用控制器定义索引ar_query = PublishedPost.order("published_posts.created_at DESC")如果 params[:searchQuery].present?search_query = params[:searchQuery]ar_query = ar_query.includes(:post =>:user).where("users.name like ?", "%#{search_query}%")结尾@found_ids = ar_query.pluck(:id)...结尾结尾
当 pluck
方法被调用时,我得到这个:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'users.name' in 'where clause': SELECT id FROM `published_posts` WHERE (users.name like '%Andrew%') ORDER BYpublished_posts.created_at DESC
我可以获得我想要的结果
@found_ids = ar_query.select(:id).map{|r|r.id}
但我更愿意使用 pluck
,因为它看起来更简洁.不过,我无法弄清楚为什么它不起作用.有什么想法吗?
您需要并且应该在此处执行 joins
而不是 includes
.
这两个函数非常相似,不同之处在于 joins
中的数据不会在查询结果中返回,而 includes
中的数据是.
在这方面,includes
和 pluck
是对立的.一个说尽可能把所有的数据都还给我,而另一个说只给我一点点.
因为你只想要少量的数据,所以你想做joins
.(奇怪的是,select
似乎也有些对立,但仍然有效,但在这种情况下,您需要消除 id
上的歧义.)
在控制台中尝试一下,您会看到 includes
会导致一个类似于这样的查询: SELECT "posts"."id" as t0_ro, "posts"."text" as t0_r1, "users"."id" as t1_r0, "users"."name" as t1_r1 ...
当你添加一个 pluck
语句时,所有这些都是疯狂的tx_ry 列消失并被您指定的任何内容替换.
我希望这有帮助,但如果没有,也许这个 RailsCast 可以.大约在 5 分钟标记处进行解释.
http://railscasts.com/episodes/181-include-vs-joins>
I have an app that has a number of Post
models, each of which belongs_to
a User
model. When these posts are published, a PublishedPost
model is created that belongs_to
the relevant Post
model.
I'm trying to build an ActiveRecord query to find published posts that match a user name, then get the ids of those published posts, but I'm getting an error when I try to use the pluck
method after eager-loading my associations and searching them with the where
method.
Here's (part of) my controller:
class PublishedPostsController < ApplicationController
def index
ar_query = PublishedPost.order("published_posts.created_at DESC")
if params[:searchQuery].present?
search_query = params[:searchQuery]
ar_query = ar_query.includes(:post => :user)
.where("users.name like ?", "%#{search_query}%")
end
@found_ids = ar_query.pluck(:id)
...
end
end
When the pluck
method is called, I get this:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'users.name' in 'where clause': SELECT id FROM `published_posts` WHERE (users.name like '%Andrew%') ORDER BY published_posts.created_at DESC
I can get the results I'm looking for with
@found_ids = ar_query.select(:id).map{|r| r.id}
but I'd rather use pluck
as it seems like the cleaner way to go. I can't figure out why it's not working, though. Any ideas?
You need to and should do joins
instead of includes
here.
The two functions are pretty similar except that the data from joins
is not returned in the result of the query whereas the data in an includes
is.
In that respect, includes
and pluck
are kind of antithetical. One says to return me all the data you possibly can, whereas the other says to only give me only this one little bit.
Since you only want a small amount of the data, you want to do joins
. (Strangely select
which also seems somewhat antithetical still works, but you would need to remove the ambiguity over id
in this case.)
Try it out in the console and you'll see that includes
causes a query that looks kind of like this: SELECT "posts"."id" as t0_ro, "posts"."text" as t0_r1, "users"."id" as t1_r0, "users"."name" as t1_r1 ...
When you tack on a pluck
statement all those crazy tx_ry columns go away and are replaced by whatever you specified.
I hope that helps, but if not maybe this RailsCast can. It is explained around the 5 minute mark.
http://railscasts.com/episodes/181-include-vs-joins
这篇关于ActiveRecord:不能在具有急切加载关联的`where` 子句之后使用`pluck`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!