2011-04-03 70 views
1

所以我有2个表加入了一个ID。我在轨控制台和I型:Rails内部加入不工作,但SQL看起来正确

Programmer.all(:joins=>:assignment) 

所生成的SQL是:

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

所产生的输出是一样的Programmer.all。为什么它不包含作业数据?

回答

5

我相信我主要对你的问题进行了较为深入的分析。如果你只是想加入程序员任何可用的任务,你正在寻找:

Programmer.all(:include => :assignment) 

导轨的设计,使:joins用于执行之类的排序,并抢得一定的记录,但仍然保持了查询结果的最小尺寸 - 意思是,:joins从未实际包含结果中连接表的结果。

现在这里是我以前的答案,假设你想执行一个INNER JOIN来获得只有程序员的任务,但你也想要这些数据。在这种情况下,你有两个选择:

#1 - 使用:select

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

,这将改变SQL语句:

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

潜在上升空间:你得到的查询你想和所有的数据至少在某处。

缺点:assignments被直接分配到Programmer对象,而不是在Programmer.assignment的适当位置。

#2 - 使用和:joins组合:includes

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

它产生SQL:

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

潜在上升空间:所有的数据是在正确的地方了。您可以参考programmer.assignment而无需其他查询。

缺点:您正在很多实例中运行额外的查询。我相当确信,Rails会在需要时尝试优化它,但是,如果不是,它不应该导致你太多的开销。

+0

这改变了SQL您列出的东西,但产量仍单纯从程序员表。 – Mason 2011-04-04 00:03:01

+0

好吧,从技术上说,它将所有这些信息添加到Programmer对象中...所以假设你有'assignment.title',它可以通过'programmer.title'访问..不太理想。 – Kelly 2011-04-04 02:27:57

+0

我已经更新了答案给你几个选项。既不像一个单一的查询那样简单,但它实质上就是你所追求的。 – Kelly 2011-04-04 03:57:29

0

只要你能做到像

Programmer.includes(:assignment)