# Polymorphic either or but not both

**URL:** <https://www.ruby-forum.com/t/polymorphic-either-or-but-not-both/84591>\
**Category:** Rails\
**Created:** [February 6, 2007, 7:27am UTC](https://www.ruby-forum.com/t/polymorphic-either-or-but-not-both/84591 "2007-02-06T07:27:02Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 6, 2007, 7:27am UTC](https://www.ruby-forum.com/t/polymorphic-either-or-but-not-both/84591/1 "2007-02-06T07:27:02Z")

</div>

I am trying to create a generic person model. Then subclass it as  
either a professor or an author. The only problem is that since some  
professors are authors, I don’t want duplicate entries. Any ideas on  
how to handle this?

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 6, 2007, 3:08pm UTC](https://www.ruby-forum.com/t/polymorphic-either-or-but-not-both/84591/2 "2007-02-06T15:08:23Z")

</div>

I wouldn’t use a polymorphic model for this, I would use single table  
inheritance.

Have a single table People with a type column, then have a model Person  
and  
subclasses for each type so:

class Person \< ActiveRecord::Base  
end

class Professor \< Person  
end

class Author \< Person  
end

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 6, 2007, 3:31pm UTC](https://www.ruby-forum.com/t/polymorphic-either-or-but-not-both/84591/3 "2007-02-06T15:31:26Z")

</div>

I just went back and re-read your original post, single table won’t  
work either since you have the possibility of a person having two  
types.

The solution is going to be a little more complex as you will need to  
create a many to many relationship.

I would use 3 tables:

```
create_table :people do |t|
  t.column :id, :integer
  t.column :name, :string
end

create_table :person_roles do |t|
  t.column :id, :integer
  t.column :person_id, :integer
  t.column :role_id, :integer
end

create_table :people do |t|
  t.column :id, :integer
  t.column :role, :string
end

```

“People” would house the information about the person, “Roles” would  
be a domain of roles a person could play (Author, professor, student),  
and “Person\_Roles” would allow the many to many.

You would then have:

class Person \< ActiveRecord::Base  
has\_many :roles, :through =\> :person\_roles  
has\_many :person\_roles  
end

Hope that helps, sorry for my hasty first post!

Joe

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [February 6, 2007, 3:34pm UTC](https://www.ruby-forum.com/t/polymorphic-either-or-but-not-both/84591/4 "2007-02-06T15:34:26Z")

</div>

I should know never to post prior to my morning caffeine intake… There  
is  
a typo on the third table definition:

> create\_table :people do |t|  
> t.column :id, :integer  
> t.column :role, :string  
> end

Should be:  
create\_table :roles do |t|  
t.column :id, :integer  
t.column :role, :string  
end
