Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveRecord Join Query and select in Rails

In my rails 4 application, a client (clients table) can have many projects (projects table). I have a column called name in each table. I am trying to write a join and then select which uses projects as the base table and clients as the lookup table. client_id is the foreign_key in the projects table:

I am writing my query as follows:

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

I get the following response:

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">]> 

If I try to alias it like so:

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

Then I get the following response:

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">]> 

In either case, ActiveRecord looses one of the names as you can see from the above response. How should I be writing this query?

like image 929
Bharat Avatar asked Mar 10 '14 22:03

Bharat


People also ask

What is ActiveRecord in Ruby on Rails?

What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.

What is difference between include and join in Rails?

:joins uses inner join, :includes uses outer join. the main reason of :includes is eager loading, to avoid the N+1 problem of loading in attributes of each object using a separate query.


2 Answers

If the column in select is not one of the attributes of the model on which the select is called on then those columns are not displayed. All of these attributes are still contained in the objects within AR::Relation and are accessible as any other public instance attributes.

You could verify this by calling first.client_name:

Project.joins(:client)        .select('projects.id,projects.name,clients.name as client_name')        .first.client_name 
like image 182
vee Avatar answered Oct 04 '22 02:10

vee


You can use :'clients.name' as one of your symbols. For instance:

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

I like it better because it seems like Rails understands it, since it quotes all parameters:

SELECT "projects"."id", "projects"."name", "clients"."name" FROM "projects" INNER JOIN "clients" ON "clients"."id" = "projects"."client_id" 

(I'm not 100% sure that's the exact SQL query, but I'm fairly certain and I promise it will use "clients"."name")

like image 28
Ryan Taylor Avatar answered Oct 04 '22 00:10

Ryan Taylor