渴望在ActiveRecord中加载多态关联

这是我第一次使用Rails,我想知道是否可以在一个SQL查询中加载一个多态关联? 它们之间的模型和关联足够基本:资产模型/表可以通过多态关联引用内容(图像,文本或音频),即

 class Asset  true
结束

图像,文本,音频定义如下:

 class Image :content
结束

当我尝试加载图片时,请这样说:

  Image.first(
       :conditions => {:id => id},
       :include =>:asset
 ) 

它指定了两个查询,一个用于检索Image,另一个用于检索资产(FYI,如果我指定了:joins ,也会发生这种情况)。 根据我的理解,ActiveRecord这样做是因为它不知道Image和Asset之间存在一对一的关联。 有没有办法强制连接并一次检索2个对象? 我也尝试使用自定义选择连接,但我最终必须手动创建ActiveRecord模型及其关联。

ActiveRecord是否提供了这样做的方法?

在深入了解Rails源代码后,我发现您可以通过在select,conditions或order子句中引用除当前模型之外的表来强制连接。

所以,如果我在Asset表上指定一个订单:

 Image.first(
       :conditions => {:id => id},
       :include =>:asset,
       :order =>“asset.id”
 )

生成的SQL将在一个语句中使用左外连接和所有内容。 我宁愿选择内部联接,但我想现在这样做。

我自己也遇到了这个问题。 与优化数据库调用相比,ActiveRecord更倾向于使Rubyist(可能甚至不太熟悉SQL)与数据库交互变得容易。 您可能必须在较低级别(例如DBI)与数据库交互以提高性能。 使用ActiveRecord肯定会影响您设计架构的方式。

对SQL效率的渴望让我想到了使用其他ORM。 我没有找到一个适合我的需求。 即使那些更倾向于转换SQL本身(例如Sequel)的人也有一个沉重的Ruby API。 我会满足于没有类似Ruby的API,只需手动编写我的T-SQL。 我使用ORM的真正好处是M,将结果集(一个或多个表)映射到对象中。

(这适用于Rails 3语法。)

MetaWhere是一个非常棒的gem,可以使复杂的查询在ActiveRecord的常用域之外轻松和像ruby一样。 (@wayne:它也支持外连接。)

https://github.com/ernie/meta_where

多态连接有点棘手。 以下是我使用MetaWhere的方法:

 Image.joins(:asset.type(AssetModel)).includes(:asset) 

事实上,我在我的多态关联类中做了一个方便的方法:

  def self.join_to(type) joins(:asset.type(type)).includes(:asset) end 

因此,它将始终查询并急切地加载特定类型的资产。 我没有尝试在一个查询中将它与多种类型的连接混合。 因为多态性使用相同的外键来引用不同的表,所以在SQL级别上,您必须将其指定为单独的连接,因为一个连接仅连接到一个表。

这仅适用于ActiveRecord 3,因为您可以访问AREL的惊人function。