1

So I have 2 tables that are joined by an ID. I'm in rails console and I type:

Programmer.all(:joins=>:assignment)

the sql that is generated is:

SELECT `programmers`.* FROM `programmers` INNER JOIN `assignments` ON `assignments`.`programmer_id` = `programmers`.`id`

The output that is generated is the same as Programmer.all. Why doesn't it include the assignments data?

animuson
  • 53,861
  • 28
  • 137
  • 147
Mason
  • 37
  • 1
  • 9

2 Answers2

5

I believe I majorly overanalyzed your question. If you just want to join any available assignments to programmers, you're looking for:

Programmer.all(:include => :assignment)

Rails is designed so that :joins is used to perform things like sorting and grabbing certain records but still keep the query result to a minimum size -- meaning, :joins never actually includes the results from the joined table in the result.

Now here's my previous answer that assumes you want to perform an INNER JOIN to get only the programmers with assignments, but you also want that data. In that case, you have two options:

#1 - Use :select

Programmer.all(:select => '*', :joins => :assignment)

That will change the SQL to:

SELECT * FROM `programmers` INNER JOIN `assignments` ON `assignments`.`programmer_id` = `programmers`.`id`

Upside: You get the query you want and all the data is somewhere, at least.

Downside: assignments is assigned directly to the Programmer object and not to the proper place at Programmer.assignment.

#2 - Use a combination of :joins and :includes

Programmer.all(:joins => :assignment, :include => :assignment)

Which produces the SQL:

SELECT `programmers`.* FROM `programmers` INNER JOIN `assignments` ON `assignments`.`id` = `programmers`.`assignment_id`
SELECT `assignments`.* FROM `assignments` WHERE (`assignments`.`id` IN  (?) )

Upside: All your data is in the right place now. You can refer to programmer.assignment without another query.

Downside: You are running that extra query in a lot of instances. I am fairly sure that Rails tries to optimize this when it needs to, though, and if not, it shouldn't cause you too much overhead.

Kelly
  • 40,173
  • 4
  • 42
  • 51
  • this changed the sql to what you have listed, but the output is still purely from the Programmer table. – Mason Apr 04 '11 at 00:03
  • well, technically it adds all of that information to the Programmer object... so say you have `assignment.title`, it would be accessible at `programmer.title`.. not ideal. – Kelly Apr 04 '11 at 02:27
  • i've updated the answer to give you a couple options. neither is as straightforward as a single query that puts everything in place, but it is essentially what you are after. – Kelly Apr 04 '11 at 03:57
0

Simply you can do like

Programmer.includes(:assignment)
Rasna Shakya
  • 527
  • 2
  • 13