ActiveRecord Join Query и выберите в Rails
В моем приложении rails 4 клиент (таблица клиентов) может иметь много проектов (таблица проектов). У меня есть столбец с именем name
в каждой таблице. Я пытаюсь написать join
, а затем select
, который использует проекты в качестве базовой таблицы и клиентов в качестве таблицы поиска. client_id
- это foreign_key
в таблице проектов:
Я пишу свой запрос следующим образом:
Project.joins(:client).select('projects.id,projects.name,clients.name')
Получаю следующий ответ:
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">]>
Если я попытаюсь сделать псевдоним таким образом:
Project.joins(:client).select('projects.id,projects.name,clients.name as client_name')
Затем я получаю следующий ответ:
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">]>
В любом случае ActiveRecord теряет одно из имен, как вы можете видеть из приведенного выше ответа. Как я должен писать этот запрос?
Ответы
Ответ 1
Если столбец в select
не является одним из атрибутов модели, на которую вызывается select
, то эти столбцы не отображаются. Все эти атрибуты все еще содержатся в объектах внутри AR::Relation
и доступны как любые другие атрибуты публичного экземпляра.
Вы можете проверить это, вызвав first.client_name
:
Project.joins(:client)
.select('projects.id,projects.name,clients.name as client_name')
.first.client_name
Ответ 2
Вы можете использовать :'clients.name'
в качестве одного из ваших символов. Например:
Project.select(:id, :name, :'clients.name').joins(:client)
Мне это нравится больше, потому что кажется, что Rails это понимает, поскольку он цитирует все параметры:
SELECT "projects"."id","projects"."name","clients"."name"
FROM "projects"
INNER JOIN "clients" ON "clients"."id" = "projects"."client_id"
(я не уверен на 100%, что точный запрос SQL, но я вполне уверен, и я обещаю, что он будет использовать "clients"."name"
)
Ответ 3
ваш запрос не теряет ничего. На самом деле вы применили присоединение к моделям, и вы написали Project.joins(: client), почему он похож.
означает, что он будет содержать связанные с Проектом данные, так как они связаны с данными с именем псевдонима, которые вы указали в своем запросе "client_name".
если вы используете
Project.joins(:client)
.select('projects.id project_id, projects.name projects_name,clients.name as client_name')
тогда это выглядит [#, #]
но он удерживает все атрибуты, которые вы выбрали.