THE CHALLENGE: How would you do this: has_many :through & polymorphic associations

Hi,

I have a category model and several other models that I want to categorize. Categories are organised in a hierarchy.

class Category < ActiveRecord::Base   acts_as_tree end

class User < ActiveRecord::Base end

class Image < ActiveRecord::Base end

I am quite sure that I am going to have additional models (like User and Images) that I want to categorize later on. It should be possible to assign a category to more than one object. For example I have a category "new" and I want to assign this category to several user and image records.

So many Images and Users could have many categories and vice versa.

I thought maybe it is possible to implement this with a has_many :through association in combination with polymorphic => true, but until now I could not fiqure out how to declare this in the models and how my migrations have to look like...

Thanks for your help.

Feurio

I believe you'll want to add an addition model for the join table that uses polymorphic associations like this:

class CategorizedItem < ARec::Base   belongs_to :category   belongs_to :categorizable, :polymorphic=>true end

class Category < ARec::Base   acts_as_tree   has_many :categoriezed_items

has_many :categorizables, :through=>:categorized_items, :source=>:categorizable end

class User < ARec::Base   has_many :categorized_items, :as=>:categorizable # could be has_one end

class Image < ARec::Base   has_many :categorized_items, :as=>:categorizable # could be has_one end

You can use the :source option (as in Categories has_many :through) to identify which association to use from the join table.

HTH, AndyV

I created the model like described by you above.

For the CategorizedItem model I used the following migration:

class CreateCategorizedItems < ActiveRecord::Migration   def self.up     create_table :categorized_items do |t|       t.references :categorizable, :null => false, :polymorphic => true       t.timestamps     end   end

  def self.down     drop_table :categorized_items   end end

use the has_many_polymorphs plugin

You're missing the 'category' half of the references:

class CreateCategorizedItems < ActiveRecord::Migration   def self.up     create_table :categorized_items do |t|       t.references :categorizable, :null => false, :polymorphic =>true       t.references :category, :null => false       t.timestamps     end   end

  def self.down     drop_table :categorized_items   end end

Sorry, still not working...

c = Category.find(943302162) => #<Category id: 943302162, name: "computer_science", description: "Informatik", parent_id: 2061879279, created_at: "2008-03-18 09:53:21", updated_at: "2008-03-18 09:53:21">

c.categorizables ActiveRecord::HasManyThroughAssociationPolymorphicError: Cannot have a has_many :through association 'Category#categorizables' on the polymorphic object 'Categorizable#categorizable'.         from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/ active_record/reflection.rb:187:in `check_validity!'         from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/ active_record/associations/has_many_through_association.rb:6:in `initialize'         from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/ active_record/associations.rb:1032:in `new'         from /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/ active_record/associations.rb:1032:in `categorizables'         from (irb):9

What I have now...

The migration files:

Hi,

thanks everybody for the help. I got it working now with the plugin has_many_polymorphs.

Would have been nice to get it working with standard rails, too. But also I was googling and used some reference books like the rails way or agile webdevelopment with rails I could find a working solution...

Feurio