Polymorphic associations?

I’ve read the stuff about polymorphic associations here:
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

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

Joe wrote:

I’ve read the stuff about polymorphic associations here:
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

On 3/24/06, Alan F. [email protected] 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

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 :stuck_out_tongue:

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

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.

On 3/24/06, Liquid [email protected] 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 :slight_smile:

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

Cheers

PA wrote:

On 3/24/06, Liquid [email protected] 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. :slight_smile: 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.