Ruby-on-rails – Eager loading of polymorphic associations in ActiveRecord

activerecordpolymorphic-associationsruby-on-rails

This is my first time using Rails and I was wondering if it's possible to load a has one polymorphic association in one SQL query? The models and associations between them are basic enough: An Asset model/table can refer to a content (either an Image, Text, or Audio) through a polymorphic association, i.e.

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

and the Image, Text, Audio are defined like this:

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

When I try to load an Image, say like this:

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

It specifies two queries, one to retrieve the Image and another to retrieve the Asset (FYI, this happens also if I specify a :joins). Based on my understanding, ActiveRecord does this because it doesn't know there's a one-to-one association between Image and Asset. Is there a way to force a join and retrieve the 2 objects in one go? I've also tried using join with a custom select, but I end up having to create the ActiveRecord models manually and their associations.

Does ActiveRecord provide a way to do this?

Best Answer

After digging through the Rails source I've discovered that you can force a join by referencing a table other than the current model in either the select, conditions or order clauses.

So, if I specify an order on the Asset table:

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

The resulting SQL will use a left outer join and everything in one statement. I would have preferred an inner join, but I guess this will do for now.

Related Topic