Bha*_*rat 38 sql activerecord ruby-on-rails
在我的rails 4应用程序中,客户端(客户端表)可以有许多项目(项目表).我name在每个表中都有一个列.我正在尝试编写一个join然后select使用项目作为基表和客户端作为查找表.client_id是foreign_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)
您可以将其:'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")
您的查询不会丢失任何东西。实际上,您已经在模型上应用了连接,并且您编写了 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)
那么它看起来像 [#, #]
但它包含您选择的所有属性。