Martin Petrov
Martin Petrov

Reputation: 2643

Polymorphic many-to-many

The following examples differ only in the Book and Movie models.

Example 1: Book has_many :taggings, :as => :taggable

Example 2: Book has_many :taggings, :through => :taggable

What does this difference mean?


Example 1:

class Book < ActiveRecord::Base
  has_many :taggings, :as => :taggable
  has_many :tags, :through => :taggings
end

class Movie < ActiveRecord::Base
  has_many :taggings, :as => :taggable
  has_many :tags, :through => :taggings
end

class Tag < ActiveRecord::Base
  has_many :taggings
  has_many :books, :through => :taggings, :source => :taggable, :source_type => "Book"
  has_many :movies, :through => :taggings, :source => :taggable, :source_type => "Movie"
end

class Tagging < ActiveRecord::Base
  belongs_to :taggable, :polymorphic => true
  belongs_to :tag
end

Example 2:

class Book < ActiveRecord::Base
  has_many :taggings, :through => :taggable
  has_many :tags, :through => :taggings
end

class Movie < ActiveRecord::Base
  has_many :taggings, :through => :taggable
  has_many :tags, :through => :taggings
end

class Tag < ActiveRecord::Base
  has_many :taggings
  has_many :books, :through => :taggings, :source => :taggable, :source_type => "Book"
  has_many :movies, :through => :taggings, :source => :taggable, :source_type => "Movie"
end


class Tagging < ActiveRecord::Base
  belongs_to :taggable, :polymorphic => true
  belongs_to :tag
end

Upvotes: 1

Views: 180

Answers (2)

piotrb
piotrb

Reputation: 364

Assuming the examples worked .. and taggable was a real model .. which as Siwei suggests probably doesn't actually work ...

:as defines a polymorphic association

and

:through says that
   if A has many B's
   and B has many C's
   then A has many C's through B

Upvotes: 1

Siwei
Siwei

Reputation: 21557

Are you sure the 2nd example works? I don't have an rails environment in windows. For my understanding about your question,

case1.

has_many :taggings, :as => :taggable

here the "taggable" is not an exact Model name, it's just an alias. (there's no Taggable class)

case2.

has_many :taggings, :through => :taggable

here the "taggable" must be an real (exsting) model, I mean there must be an Taggable class somewhere.

refer: http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

Upvotes: 1

Related Questions