<?xml version="1.0" encoding="UTF-8"?>
<post>
  <body>&lt;p&gt;Setting up polymorphic associations is ridiculously easy in Rails.&amp;nbsp; Setting up many-to-many associations in Rails is &lt;em&gt;also&lt;/em&gt; ridiculously easy in Rails.&amp;nbsp; However, setting up polymorphic many-to-many associations in Rails is more difficult, but only slightly.&lt;/p&gt;
&lt;p&gt;Recently, on an &lt;a href="http://www.intridea.com"&gt;Intridea&lt;/a&gt; client project, I had one particular model that had many-to-many associations with several other models in the app.&amp;nbsp; The thought of multiple join tables in the database didn't sit well with me, so I decided to consolidate things a bit.&lt;/p&gt;
&lt;p&gt;Now I can't use the actual models from the app without possibly giving away the yet-to-be-launched app.&amp;nbsp; So instead, I'll use an example that we're all familiar with, tags and taggings.&lt;/p&gt;
&lt;p&gt;You know the drill.&amp;nbsp; You have your common model, Tag.&lt;/p&gt;
&lt;pre name="code" class="ruby"&gt;class Tag &amp;lt; ActiveRecord::Base
  has_many :taggings, :dependent =&amp;gt; :destroy
  has_many :books, :through =&amp;gt; :tagings, :source =&amp;gt; :taggable, :source_type =&amp;gt; "Book"
  has_many :movies, :through =&amp;gt; :tagings, :source =&amp;gt; :taggable, :source_type =&amp;gt; "Movie"
end
&lt;/pre&gt;
&lt;p&gt;Your join model, Tagging.&lt;/p&gt;
&lt;pre name="code" class="ruby"&gt;class Tagging &amp;lt; ActiveRecord::Base
  belongs_to :taggable, :polymorphic =&amp;gt; true
  belongs_to :tag
end
&lt;/pre&gt;
&lt;p&gt;And your taggable models, Book and Movie.&lt;/p&gt;
&lt;pre name="code" class="ruby"&gt;class Book &amp;lt; ActiveRecord::Base
  has_many :taggings, :as =&amp;gt; :taggable
  has_many :tags, :through =&amp;gt; :taggings
end

class Movie &amp;lt; ActiveRecord::Base
  has_many :taggings, :as =&amp;gt; :taggable
  has_many :tags, :through =&amp;gt; :taggings
end
&lt;/pre&gt;
&lt;p&gt;Everything in Tagging, Movie, and Book is pretty much your standard setup.&amp;nbsp; This gives you all the normal associations.&amp;nbsp; You've got tag.taggings, book.tags, movie.tags, and tag.taggable.&lt;/p&gt;
&lt;p&gt;It gets a little trickier when you want to find all movies (or books) associated with a tag.&amp;nbsp; There are a number of ways that this can be done.&amp;nbsp; You could use some crazy joined finder call on Movie, or find all Taggings with a particular taggable type (or a named scope) and collect the movies, or do it like up above.&lt;/p&gt;
&lt;pre name="code" class="ruby"&gt;has_many :movies, :through =&amp;gt; :tagings, 
                  :source =&amp;gt; :taggable, 
                  :source_type =&amp;gt; "Movie"
&lt;/pre&gt;
&lt;p&gt;This association allows us to access a movies with a particular tag directly from the tag object itself.&amp;nbsp; It's just your typical &lt;em&gt;has_many&lt;/em&gt; association, but with a few more options.&amp;nbsp; The &lt;em&gt;:through&lt;/em&gt; option says that movies can be accessed through our join model, tagging.&amp;nbsp; Rails normally would expect there to be a movies association on tagging, but the &lt;em&gt;:source&lt;/em&gt; option tells Rails to examine the taggable association instead.&amp;nbsp; Similarly, the &lt;em&gt;:source_type&lt;/em&gt; option specifies the class (or type) of the polymorphic association that we trying to retrieve.&lt;/p&gt;
&lt;p&gt;So remember when you want bidirectional class-specific many-to-many polymorphic associations, :source and :source_type are your friend.&lt;/p&gt;</body>
  <created-at type="datetime">2009-04-12T17:38:26Z</created-at>
  <description>Setting up polymorphic associations is ridiculously easy in Rails.? Setting up many-to-many associations in Rails is also ridiculously easy in Rails.? </description>
  <id type="integer">26</id>
  <keywords></keywords>
  <published type="boolean">true</published>
  <slug>polymorphic-many-to-many-associations-in-rails</slug>
  <title>Polymorphic many-to-many associations in Rails</title>
  <updated-at type="datetime">2009-05-04T04:05:23Z</updated-at>
</post>
