I am setting up a tagging system using polymorphism and it works about
half the way I would expect it to. One thing in my app that can be
tagged is blogs. I am able to tag them and it works as I expect when I
save the blog and when I call blog.tags it returns the list of tags
associated with that blog. The thing that does not work is when I am
trying to display a list of all the blogs for a certain tag. For
example:
tag = Tag.find(1)
tag.blogs ## => returns nil
Here is my setup:
class Tag < ActiveRecord::Base
end
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :taggable, :polymorphic => true
end
class Blog < ActiveRecord::Base
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
##when I save a blog in my controller, I do this to assign a tag to it
blog = Blog.find(1)
tagging = Tagging.new(:tag_id=>tag_id)
tagging.taggable = blog
tagging.save
I have tried experimenting with all kinds of things in the Tag model
(ex: has_many :blogs, :through =>:taggings), but nothing seems to work.
What am I missing? Maybe I am misunderstanding how polymorphism works
or maybe there is a better way to set this up in general.
One of the existing plugins such as acts_as_taggable_on_steroids might
have this functionality already… I’m not sure though.
Here’s one way to do it:
class Blog < ActiveRecord::Base
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
class Tagging < ActiveRecord::Base
belongs_to :tag
belongs_to :taggable, :polymorphic => true
end
class Tag < ActiveRecord::Base
has_many :taggings
def get(taggable)
self.taggings.all(:conditions => [“taggable_type = ?”,
taggable.to_s.singularize.camelize]).map(&:taggable)
end
end
require ‘test_helper’
class TagTest < ActiveSupport::TestCase
test ‘should get taggable type’ do
tag = Tag.create(:name => ‘blogtag’)
blog1 = Blog.create(:name => ‘blog1’)
blog1.tags << tag
blog2 = Blog.create(:name => ‘blog2’)
blog2.tags << tag