Polymorphism question

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.

Thanks in advance! John

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

    assert_equal [tag], blog1.tags     assert_equal [blog1, blog2], tag.get(:blogs)   end

end

Hello Yanni mac,

You can use acts-as-taggable-on plugin for same purpose.

Cheers ! Sandip