# Polymorphic associations?

**URL:** <https://www.ruby-forum.com/t/polymorphic-associations/55840>\
**Category:** Rails\
**Created:** [March 24, 2006, 8:06am UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840 "2006-03-24T08:06:49Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 8:06am UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/1 "2006-03-24T08:06:49Z")

</div>

I’ve read the stuff about polymorphic associations here:  
[http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations](http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations)

But I’m not sure what exactly they are and what their advantage is. Are  
they the same as HABTM, but they’re “two-way”?

Joe

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 10:50am UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/2 "2006-03-24T10:50:18Z")

</div>

Yikes! I just read what I wrote earlier. I guess my cold my be  
scrambling my brain. Please ignore my earlier reply.

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 11:48am UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/3 "2006-03-24T11:48:28Z")

</div>

Joe wrote:

> I’ve read the stuff about polymorphic associations here:  
> [http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations](http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations)
> 
> But I’m not sure what exactly they are and what their advantage is. Are  
> they the same as HABTM, but they’re “two-way”?

They do for the relational model what Polymorphism does for a more  
traditional Object model.

If I have a Company which employs several Employees and theose Employees  
could be Janitors (with a floor to clean), Managers with a department to  
manage, or Workers with a JobSpec, it was hard before to say that  
COmpany has\_many Employees as they were spread across the managers,  
janitors and workers tables.

With Polymorphic associations we can fix this and connect the Company  
with those 3 types of employee.

Does this help clarify ?

Alan

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 12:21pm UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/4 "2006-03-24T12:21:22Z")

</div>

On 3/24/06, Alan F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> If I have a Company which employs several Employees and theose Employees  
> could be Janitors (with a floor to clean), Managers with a department to  
> manage, or Workers with a JobSpec, it was hard before to say that  
> COmpany has\_many Employees as they were spread across the managers,  
> janitors and workers tables.

Wouldn’t that be more reasonably described as an ‘Employee’ ‘has\_one’ or  
‘has\_many’ ‘Role’?

After all, people can change role or have many of them. I doubt you will  
want to have a EmployeJanitorManagerWorker lurking in your class  
hierarchy  
8^)

–  
Cheers

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 12:38pm UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/5 "2006-03-24T12:38:13Z")

</div>

PA wrote:

> Wouldn’t that be more reasonably described as an ‘Employee’ ‘has\_one’ or  
> ‘has\_many’ ‘Role’?

Yes, except that would (pre 1.1) force you have a single ‘Employee’  
class, or use STI to hack the subclasses.

> After all, people can change role or have many of them. I doubt you will  
> want to have a EmployeJanitorManagerWorker lurking in your class  
> hierarchy  
> 8^)

Well, to be fair, they can only switch roles, or have many roles if I  
say they can, as this is my app 😛

Hmm, my example is doing what languages like Java do, mixing  
Polymorphism with Inheritance. Perhaps a better examples is the one  
from Chad’s Rails Recipes.

Say we have an Address. a Person can have an Address, or a Company can  
have an address. Person and Company are entirely different concepts,  
sharing no attributes or functionality other than that they both has\_one  
:address. WHat to put in the Address side ?

We could have has\_many :people AND has\_many :companies but that makes it  
hard to do something across all things at this address.

With Polymorphic associations we can say that an Address belongs\_to  
:addressable

For a fuller working, and much, much clearer explanations(of this and  
other 1.1 features), run, don’t walk to the PragBookshelf site and buy  
Rails Recipes.

Alan

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 12:43pm UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/6 "2006-03-24T12:43:52Z")

</div>

If I had a system that had Employees, Projects, Actions, and Messages  
(just  
a hyperthetical)

I want each one of these to have\_many documents.

In the traditional way of has\_many on each of these I would need a field  
or  
foreign key in the document table for each of these types. employee\_id,  
project\_id, action\_id etc  
If I were to add a new model that I want to have documents attached to I  
would need to modify the table to include a new foreign key.  
If I then decide that I want a list of all documents and I want to find  
the  
owning thing, I need to search each of these fields and work out which  
association it belongs to.

With a polymorphic association all this is done away with. By declaring  
class Document \< ActiveRecord::Base  
belongs\_to :documentable, :polymorphic =\> true  
end

I can assign documents to any model that want’s them with no change to  
the  
schema. Also the getting and setting methods are straight forward and  
consistant. One nice thing that polymophic associations allow you to  
easily  
do is to go to the owning resource.

It’s not quite a habtm because it can belong to many many’s if that  
makes  
sense.

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 2:24pm UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/7 "2006-03-24T14:24:47Z")

</div>

On 3/24/06, Liquid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> If I had a system that had Employees, Projects, Actions, and Messages (just a hyperthetical)
> 
> I want each one of these to have\_many documents.
> 
> In the traditional way of has\_many on each of these I would need a field or foreign key in the document table for each of these types. employee\_id, project\_id, action\_id etc

What about a simple intermediary table which describes the association  
between ‘Owner’ and ‘Document’? The intermediaty table could capture  
both the ‘Owner’ identifier and its type.

In any case, there are many way to skin that particular cat 🙂

To paraphrase EOF:

Some of the issues you need to weigh in deciding on an approach are:

- …
- Do I need to use inheritance at all?

– Enterprise Objects Framework Developer’s Guide, Modeling Inheritance

[http://developer.apple.com/documentation/LegacyTechnologies/WebObjects/WebObjects\_4.0/System/Documentation/Developer/EnterpriseObjects/Guide/EOsII3.html](http://developer.apple.com/documentation/LegacyTechnologies/WebObjects/WebObjects_4.0/System/Documentation/Developer/EnterpriseObjects/Guide/EOsII3.html)

Cheers

---

<div class="post-metadata">

**Author:** ![joe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b9e5f3/32.png) [@joe](https://www.ruby-forum.com/u/joe)\
**Post date:** [March 24, 2006, 2:43pm UTC](https://www.ruby-forum.com/t/polymorphic-associations/55840/8 "2006-03-24T14:43:39Z")

</div>

PA wrote:

> On 3/24/06, Liquid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > If I had a system that had Employees, Projects, Actions, and Messages (just a hyperthetical)
> > 
> > I want each one of these to have\_many documents.
> > 
> > In the traditional way of has\_many on each of these I would need a field or foreign key in the document table for each of these types. employee\_id, project\_id, action\_id etc
> 
> What about a simple intermediary table which describes the association  
> between ‘Owner’ and ‘Document’? The intermediaty table could capture  
> both the ‘Owner’ identifier and its type.

It’s not that it couldn’t be done before, its that we had to resort to  
‘instanceof’-like hacks like that to implement whats a fairly clear  
model in abstract. 🙂 Employees, Projects and Actions are distinct  
types, with distinct models etc that just happen to be linked to  
Document. Polymorphic Associations model that DRYly.

A.
