Dans mon application Rails 4, un client (table clients) peut avoir plusieurs projets (table projets). J'ai une colonne appelée name
dans chaque table. J'essaie d'écrire un join
puis select
qui utilise des projets comme table de base et des clients comme table de recherche. client_id
est le foreign_key
dans le tableau des projets:
J'écris ma requête comme suit:
Project.joins(:client).select('projects.id,projects.name,clients.name')
J'obtiens la réponse suivante:
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">]>
Si j'essaie de l'alias comme ça:
Project.joins(:client).select('projects.id,projects.name,clients.name as client_name')
Ensuite, j'obtiens la réponse suivante:
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">]>
Dans les deux cas, ActiveRecord perd l'un des noms comme vous pouvez le voir dans la réponse ci-dessus. Comment dois-je écrire cette requête?
Si la colonne dans select
ne fait pas partie des attributs du modèle sur lequel la select
est appelée, ces colonnes ne sont pas affichées. Tous ces attributs sont toujours contenus dans les objets dans AR::Relation
et sont accessibles comme tout autre attribut d'instance publique.
Vous pouvez le vérifier en appelant first.client_name
:
Project.joins(:client)
.select('projects.id,projects.name,clients.name as client_name')
.first.client_name
Vous pouvez utiliser :'clients.name'
Comme l'un de vos symboles. Par exemple:
Project.select(:id, :name, :'clients.name').joins(:client)
Je l'aime mieux car il semble que Rails le comprend, car il cite tous les paramètres:
SELECT "projects"."id","projects"."name","clients"."name" as "client_name" FROM "projects" INNER JOIN "clients" ON "clients"."id" = "projects"."client_id"
(Je ne suis pas sûr à 100% que c'est la requête SQL exacte, mais je suis assez certain et je le promets va utiliser "clients"."name"
)
votre requête ne perd rien. En fait, vous avez appliqué la jointure sur des modèles et vous avez écrit Project.joins (: client) à quoi cela ressemble. signifie qu'il contiendra les données liées au projet telles quelles et les données associées avec le nom d'alias que vous avez donné 'client_name' dans votre requête.
si tu utilises
Project.joins(:client)
.select('projects.id project_id, projects.name projects_name,clients.name as client_name')
alors ça ressemble à [#, #]
mais il contient tous les attributs que vous avez sélectionnés.