views:

83

answers:

2

I'm writing some tricky polymorphic relationships to handle tagging.

I have a Tag model, and a Tagging model which belongs_to a polymorphic taggable.

I have an Item model, which has_many :taggings, :as => :taggable, and has_many :tags, :through => :taggings, so that I can call @item.tags.

This is all working ok.

I want to bring another model into the mix - a Store which has_many :items. I want to be able to find all tags associated with all items in the store using @store.tags.

Here's what I have:

class Store < AR::Base
  has_many :items
  has_many :tags, :through => :items, :source => :taggings

However, this returns all of the taggings associated with items in the store, not the actual tags.

How do I get specify that the store has_many tags, through items, through taggings?

Can post more info if needed - trying to prevent information overload! Thanks :)

A: 

You can do in plain Ruby:

site.wares.map(&:tags).flatten.uniq

This will be inefficient though, unless you have a low number of tags / wares / items.

François Beausoleil
+2  A: 

The source for a has_many association must be a belongs_to, has_one, or has_many association without a :through option (thanks to this answer for info).

There is a plugin that some people have had success with, but in my case it didn't seem to work correctly with my taggable polymorphic association.

At the moment, my solution is to pass a finder_sql option to has_many:

class Store < ActiveRecord::Base
  has_many :items
  has_many :tags, :finder_sql => 
    'SELECT tags.* from tags
      INNER JOIN taggings on tags.id = taggings.tag_id
      INNER JOIN items on items.id = taggings.taggable_id AND taggings.taggable_type = "Item"
      WHERE items.store_id = #{id}'

end
nfm