# THE CHALLENGE: How would you do this: has\_many :through & polymorphic associations

**URL:** <https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150>\
**Category:** Rails\
**Created:** [March 17, 2008, 1:27pm UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150 "2008-03-17T13:27:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Feurio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Feurio](https://www.ruby-forum.com/u/Feurio)\
**Post date:** [March 17, 2008, 1:27pm UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150/1 "2008-03-17T13:27:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Feurio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Feurio](https://www.ruby-forum.com/u/Feurio)\
**Post date:** [March 17, 2008, 1:57pm UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150/2 "2008-03-17T13:57:30Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Feurio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Feurio](https://www.ruby-forum.com/u/Feurio)\
**Post date:** [March 17, 2008, 3:30pm UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150/3 "2008-03-17T15:30:20Z")

</div>

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

* * *

Sadly it seems not to work (completly).

> > c = Category.create  
> > =\> #\<Category id: 2061879280, name: nil, description: nil, parent\_id:  
> > nil, created\_at: “2008-03-17 15:16:18”, updated\_at: “2008-03-17  
> > 15:16:18”\>
> 
> > 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):4

The following seems to work, but how would I assign a Category to a  
Uses?

u = User.create  
=\> #\<User id: 2, created\_at: “2008-03-17 15:17:27”, updated\_at:  
“2008-03-17 15:17:27”\>

> > u.categorized\_items  
> > =\> []

Thanks,

Feurio

---

<div class="post-metadata">

**Author:** ![Feurio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Feurio](https://www.ruby-forum.com/u/Feurio)\
**Post date:** [March 17, 2008, 9:23pm UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150/4 "2008-03-17T21:23:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Feurio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Feurio](https://www.ruby-forum.com/u/Feurio)\
**Post date:** [March 17, 2008, 3:53pm UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150/5 "2008-03-17T15:53:29Z")

</div>

use the has\_many\_polymorphs plugin

---

<div class="post-metadata">

**Author:** ![Feurio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Feurio](https://www.ruby-forum.com/u/Feurio)\
**Post date:** [March 18, 2008, 10:04am UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150/6 "2008-03-18T10:04:11Z")

</div>

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:

class CreateCategories \< ActiveRecord::Migration  
def self.up  
create\_table :categories do |t|  
t.string :name, :description  
t.integer :parent\_id  
t.timestamps  
end  
end

def self.down  
drop\_table :categories  
end  
end

class CreateUsers \< ActiveRecord::Migration  
def self.up  
create\_table :users do |t|

```
  t.timestamps
end

```

end

def self.down  
drop\_table :users  
end  
end

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

## The models:

class Category \< ActiveRecord::Base  
acts\_as\_tree  
has\_many :categorized\_items  
has\_many :categorizables, :through =\> :categorized\_items, :source  
=\> :categorizable  
end

class User \< ActiveRecord::Base  
has\_many :categorized\_items, :as=\>:categorizable # could be has\_one  
end

class CategorizedItem \< ActiveRecord::Base  
belongs\_to :category  
belongs\_to :categorizable, :polymorphic=\>true  
end

* * *

And how would I do something like the following with the associations  
above?

c = Category.create  
u = User.create  
u.categories \<\< Category

Thanks for your patience!

Feurio

---

<div class="post-metadata">

**Author:** ![Feurio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/3bc359/32.png) [@Feurio](https://www.ruby-forum.com/u/Feurio)\
**Post date:** [March 18, 2008, 6:27pm UTC](https://www.ruby-forum.com/t/the-challenge-how-would-you-do-this-has-many-through-polymorphic-associations/132150/7 "2008-03-18T18:27:36Z")

</div>

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
