model question


I'm building a contact management system for a small school and I'm
having trouble coming up with the right data-model that works well with

Here's the mysql




The contact table contains basic stuff that all contacts will have, and
subsequent models extend Contact to add additional data. Some of the
sub models are Donor, Faculty, Director. A single Contact can be a
Donor, Faculty, and a Director, so it's what I think is called
multi-table inheritance which isn't really supported in Rails. Some of
the workarounds I've seen seemed overly complex.

I was planning to do something like this:
class Donor < ActiveRecord::Base
has_one :contact

for all the sub models and I think that would work, but I can't use the
syntax Donor.find(1, :include => :contact) because this requires a
donor_id column in contacts, and I doesn't seem to be good to have
donor_id, faculty_id, director_id, foreign key columns in contacts
(maybe this isn't a problem??) Also, assuming the above, when I create
one of the sub models I can't get the contact_id to save to donor

@contact =[:contact])
@donor =[:donor])
Donor.transaction do
  @donor.contact_id =
    flash[:notice] = 'Donor was successfully created.'
    redirect_to :action => 'list'
    render :action => 'new'

I can get the schema above to work, but I think I'll have to do a lot
of custom sql to make it work rather than using the built-in :include.
Unless there's a way to "reverse" the underlying join of the has_one
relationship so a contact_id in donors joins to contacts?

Thanks for the help!


Just reverse the relationship, as you suggested:

class Donor < ActiveRecord::Base
  belongs_to :contact

class Contact < ActiveRecord::Base
  has_one :donor
  has_one :faculty
  has_one :director

Rails will then use the contact_id field in Donor, Faculty etc. and you
won't need the donor_id and other id fields in Contact.

Hello again,

I've been thinking about this some more and I think the easiest thing
to do is to put foreign key columns in contacts for each of the
sub-models. While this would require a schema change in contacts for
every "new" sub-model, that's okay for this project.

By doing this, I'm not polluting the elegant natural language of rails.
The Donor can :has_one Contact, and I can do a Donor.find(1, :include
=> :contact).

The following code worked great:

c =
d = = c

=> 1

Donor.find(1, :include => :contact)

Regardless, I'm still looking forward to other ideas.

You're completely correct, I learned that this would work after my
first post, but I was conflicted in saying that a Donor belongs to a
Contact, because it didn't really describe the relationship. Anyway,

You really shouldn't get caught up with the descriptions "has_one" and
"belongs_to". In rails they mean little more than "I don't have the
foreign key" and "I do have the foreign key". There's no reason why the
item that "belongs to" another item needs to have the foreign key. And
rails will work quite happily either way. All the code you used in your
example will work identically if you reverse the relationship (except
for c.donor_id, obviously). In particular, the ":include => contact"
will still work with the relationship reversed.

I've used this "reverse relationship" in a couple of places in my
current project because it simply makes more sense that way. And rails
hasn't complained once.