stiig
9/26/2011 - 3:23 PM

Reverse polymorphic associations in Rails

Reverse polymorphic associations in Rails

class Article < ActiveRecord::Base
  has_many :article_elements
  has_many :pictures, :through => :article_elements, :source => :element, :source_type => 'Picture'
  has_many :videos, :through => :article_elements, :source => :element, :source_type => 'Video'
end

class Picture < ActiveRecord::Base
  has_one :article_element, :as =>:element
  has_one :article, :through => :article_elements
end

class Video < ActiveRecord::Base
  has_one :article_element, :as =>:element
  has_one :article, :through => :article_elements 
end

class ArticleElement < ActiveRecord::Base
  belongs_to :article
  belongs_to :element, :polymorphic => true
end

t = Article.new
t.article_elements  # []
p = Picture.new
t.article_elements.create(:element => p)
t.article_elements  # [<ArticleElement id: 1, article_id: 1, element_id: 1, element_type: "Picture", created_at: "2011-09-26 18:26:45", updated_at: "2011-09-26 18:26:45">]
t.pictures # [#<Picture id: 1, created_at: "2011-09-26 18:26:45", updated_at: "2011-09-26 18:26:45">]

Polymorphic Associations reversed

It's pretty easy to do polymorphic associations in Rails: A Picture can belong to either a BlogPost or an Article. But what if you need the relationship the other way around? A Picture, a Text and a Video can belong to an Article, and that article can find all media by calling @article.media

This example shows how to create an ArticleElement join model that handles the polymorphic relationship. To add fields that are common to all polymorphic models, add fields to the join model.