web-dev-qa-db-ja.com

ActiveRecord Join Queryを選択して、Rails

私のRails 4アプリケーションでは、クライアント(clientsテーブル)は多くのプロジェクト(projectsテーブル)を持つことができます。各テーブルにnameという列があります。 joinに続いてselectは、プロジェクトをベーステーブルとして使用し、クライアントをルックアップテーブルとして使用しますclient_idはprojectsテーブルの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つを失います。このクエリをどのように書くべきですか?

34
Bharat

selectの列が、selectが呼び出されるモデルの属性のいずれでもない場合、それらの列は表示されません。これらの属性はすべてAR::Relation内のオブジェクトに含まれており、他のパブリックインスタンス属性としてアクセスできます。

これを確認するには、first.client_nameを呼び出します。

Project.joins(:client)
       .select('projects.id,projects.name,clients.name as client_name')
       .first.client_name
81
vee

_:'clients.name'_をシンボルの1つとして使用できます。例えば:

Project.select(:id, :name, :'clients.name').joins(:client)

Railsはすべてのパラメーターを引用するため、Rails $ ===はそれを理解しているように見えるので、私はそれがより好きです:

_SELECT "projects"."id","projects"."name","clients"."name" as "client_name" FROM "projects" INNER JOIN "clients" ON "clients"."id" = "projects"."client_id"_

(私はそれが正確なSQLクエリであることを100%確信しているわけではありませんが、私はかなり確信しており、それを約束しますwill use _"clients"."name"_)

4
Ryan Taylor

クエリで何かが失われることはありません。実際に、モデルに結合を適用し、Project.joins(:client)を記述して、その理由を説明します。は、プロジェクト関連のデータをそのまま保持し、クエリで「client_name」を指定したエイリアス名に関連付けられたデータを保持することを意味します。

使用する場合

Project.joins(:client)
   .select('projects.id project_id, projects.name projects_name,clients.name as client_name')

[#、#]のようになります

ただし、選択したすべての属性が保持されます。

3
uma