ActiveRecord加入查询并在Rails中选择

Bha*_*rat 38 sql activerecord ruby-on-rails

在我的rails 4应用程序中,客户端(客户端表)可以有许多项目(项目表).我name在每个表中都有一个列.我正在尝试编写一个join然后select使用项目作为基表和客户端作为查找表.client_idforeign_key项目表中的:

我写的查询如下:

Project.joins(:client).select('projects.id,projects.name,clients.name')
Run Code Online (Sandbox Code Playgroud)

我收到以下回复:

Project Load (0.6ms)  SELECT projects.id,projects.name,clients.name FROM "projects" INNER JOIN "clients" ON "clients"."id" = "projects"."client_id"
=> #<ActiveRecord::Relation [#<Project id: 1, name: "Fantastico Client">]>
Run Code Online (Sandbox Code Playgroud)

如果我试着像这样别名:

Project.joins(:client).select('projects.id,projects.name,clients.name as client_name')
Run Code Online (Sandbox Code Playgroud)

然后我得到以下回复:

Project Load (0.8ms)  SELECT projects.id,projects.name,clients.name as client_name FROM "projects" INNER JOIN "clients" ON "clients"."id" = "projects"."client_id"
=> #<ActiveRecord::Relation [#<Project id: 1, name: "The Dream Project">]>
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,ActiveRecord都会丢失其中一个名称,您可以从上面的响应中看到.我该怎么写这个查询?

vee*_*vee 85

如果列in select不是select调用它的模型的属性之一,则不显示这些列.所有这些属性仍包含在其中的对象中AR::Relation,并且可以作为任何其他公共实例属性访问.

你可以通过调用来验证这个first.client_name:

Project.joins(:client)
       .select('projects.id,projects.name,clients.name as client_name')
       .first.client_name
Run Code Online (Sandbox Code Playgroud)

  • 如果你做project = Project.joins(:client).select('projects.id,projects.name,clients.name').然后执行project.first.attributes,你会看到缺少的列.就像Vee说它只显示"项目"模型记录. (2认同)

Rya*_*lor 7

您可以将其:'clients.name'用作符号之一。例如:

Project.select(:id, :name, :'clients.name').joins(:client)
Run Code Online (Sandbox Code Playgroud)

我更喜欢它,因为看起来Rails可以理解,因为它引用了所有参数:

SELECT "projects"."id", "projects"."name", "clients"."name"
FROM "projects"
INNER JOIN "clients" ON "clients"."id" = "projects"."client_id"
Run Code Online (Sandbox Code Playgroud)

(我不是100%肯定这是确切的SQL查询,但我敢肯定,我保证它使用"clients"."name"


小智 7

要获取项目表名称和客户名称,您可以执行以下查询

Project.joins(:client).pluck(:name,:'clients.name')


uma*_*uma 5

您的查询不会丢失任何东西。实际上,您已经在模型上应用了连接,并且您编写了 Project.joins(:client) 这就是为什么它看起来像。意味着它将按原样保存与项目相关的数据,并使用您在查询中指定的“client_name”别名保存相关数据。

如果你使用

Project.joins(:client)
   .select('projects.id project_id, projects.name projects_name,clients.name as client_name')
Run Code Online (Sandbox Code Playgroud)

那么它看起来像 [#, #]

但它包含您选择的所有属性。