在ActiveRecord的多态关联的预先加载(Eager loading of polymorph

2019-08-16 19:41发布

这是用我的第一次Rails和我在想,如果有可能加载在一个SQL查询一个多态关联? 这些模型和它们之间的关联是基本够用了:一个资产模型/表可以参考内容(无论是图片,文字或声音)通过一个多态关联,即

class Asset < ActiveRecord::Base
  :belongs_to :content, :polymorphic => true
end

和图像,文本,音频的定义是这样的:

class Image < ActiveRecord::Base
  :has_one :asset, :as => :content
end

当我尝试加载图像,这样说:

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

它指定了两个查询,来检索图像和其他检索资产(仅供参考,出现这种情况也是,如果我指定一个:joins )。 根据我的理解,ActiveRecord的这样做,因为它不知道有图片和资产之间的一个一对一的关联。 有没有办法强制参加并获取2个对象一气呵成? 我已经使用了自定义的加入也选择尝试过,但我最终不得不手动创建ActiveRecord的模式和他们的关联。

是否ActiveRecord的提供一种方式来做到这一点?

Answer 1:

通过Rails源我发现,你可以强制挖后通过引用比在任一选择,条件或条款顺序当前模型以外的表连接。

所以,如果我指定的资产表中的顺序:

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

生成的SQL将使用一个左外连接,一切都在一个声明。 我宁愿一个内部联接,但我想这会为现在要做的。



Answer 2:

我撞到这个问题我自己。 ActiveRecord的更倾向于使它容易对Ruby开发者的结束(谁甚至可能不是太熟悉SQL)倾斜与数据库接口,比采用优化的数据库调用一样。 您可能必须在一个较低的水平(例如DBI)与数据库进行交互,以提高你的表现。 使用ActiveRecord肯定会影响您设计的架构。

对于SQL效率的渴望让我想到使用其他的ORM。 我还没有找到一个适合我的需要。 即使是那些移动更倾向于事务SQL本身(例如续集)有一个沉重的Ruby API。 我将是一个没有Ruby的API内容,只是手动写我的T-SQL。 与ORM后我是真正的好处是M,映射结果集(的一个或多个表)插入的对象。



Answer 3:

(这是为Rails 3语法)。

MetaWhere是制造复杂的查询,以及本身的ActiveRecord通常的域名容易与红宝石般以外的真棒宝石。 (@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惊人的力量。



文章来源: Eager loading of polymorphic associations in ActiveRecord