如何通过Rails中的自定义联接渴望加载对象?

时间:2020-03-06 14:41:32  来源:igfitidea点击:

背景

渴望加载收藏集的普通方法是这样的:

Person.find(:all, :include=>:companies)

这会生成一些sql

LEFT OUTER JOIN companies ON people.company_id = companies.id

问题

但是,我需要一个自定义的联接(如果我使用find_by_sql也会出现这种情况),所以我不能使用普通的:include =>:companies

自定义的join / sql将为我获取所需的所有数据,但是如何告诉activerecord它属于关联的" Company"对象,而不仅仅是一堆额外的行?

更新

我需要在联接中添加其他条件。像这样的东西:

SELECT blah blah blah
LEFT OUTER JOIN companies ON people.company_id = companies.id AND people.magical_flag IS NULL 
<Several other joins>
WHERE blahblahblah

解决方案

我们不能使用ActiveRecord添加连接条件吗?

例如,我有一个非常复杂的查询,使用了多个相关记录,并且通过组合条件和include指令可以很好地工作

Contractors.find(
  :all, 
  :include => {:council_areas => :suburbs},
  :conditions => ["suburbs.postcode = ?", customer.postcode]                 
)

假如说:

  • 承包商有多个委员会区域
  • CouncilAreas有许多郊区

此联接返回由customer.postcode标识的郊区的承包商。

生成的查询如下所示:

SELECT contractors.*, council_areas.*, suburbs.*
FROM `contractors` 
LEFT OUTER JOIN `contractors_council_areas` ON `contractors_council_areas`.contractor_id = `contractors`.id 
LEFT OUTER JOIN `council_areas` ON `council_areas`.id = `contractors_council_areas`.council_area_id 
LEFT OUTER JOIN `council_areas_suburbs` ON `council_areas_suburbs`.council_area_id = `council_areas`.id 
LEFT OUTER JOIN `suburbs` ON `suburbs`.id = `council_areas_suburbs`.suburb_id WHERE (suburbs.postcode = '5000')

(注意:为简便起见,我编辑了列列表)。

我们能否进一步详细说明我们要通过此查询尝试完成的工作?

还可以看一下:joins选项来查找。它允许我们指定希望如何连接表。连结文字

并且要当心使用:include时,该行为在Rails 2.1中会有所变化,并且与与引用包含表的:conditions选项一起使用时,可能会导致一些问题。链接文本和链接文本是Pivotal提到这两点的两篇文章。

我们可以使用类似以下的内容来获取适当的左外连接句法魔术。

Person.reflect_on_association(:companies).options[:conditions] = 'people.magical_flag IS NULL'