# Model question

**URL:** <https://www.ruby-forum.com/t/model-question/81829>\
**Category:** Rails\
**Created:** [January 15, 2007, 4:30pm UTC](https://www.ruby-forum.com/t/model-question/81829 "2007-01-15T16:30:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mveerman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c57346/32.png) [@mveerman](https://www.ruby-forum.com/u/mveerman)\
**Post date:** [January 15, 2007, 4:30pm UTC](https://www.ruby-forum.com/t/model-question/81829/1 "2007-01-15T16:30:59Z")

</div>

Hello,

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  
Rails.

Here’s the mysql  
contacts  
id  
first\_name  
last\_name  
…

donors  
id  
contact\_id  
status  
…

faculty  
id  
contact\_id  
hire\_date

directors  
id  
contact\_id

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  
end

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  
automatically.

@contact = Contact.new(params[:contact])  
@donor = Donor.new(params[:donor])  
Donor.transaction do  
@contact.save  
@donor.contact\_id = @contact.id  
if @donor.save  
flash[:notice] = ‘Donor was successfully created.’  
redirect\_to :action =\> ‘list’  
else  
render :action =\> ‘new’  
end  
end

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!

Mark

---

<div class="post-metadata">

**Author:** ![mveerman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c57346/32.png) [@mveerman](https://www.ruby-forum.com/u/mveerman)\
**Post date:** [January 15, 2007, 4:32pm UTC](https://www.ruby-forum.com/t/model-question/81829/2 "2007-01-15T16:32:59Z")

</div>

Just reverse the relationship, as you suggested:

class Donor \< ActiveRecord::Base  
belongs\_to :contact  
end

class Contact \< ActiveRecord::Base  
has\_one :donor  
has\_one :faculty  
has\_one :director  
end

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.

---

<div class="post-metadata">

**Author:** ![mveerman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c57346/32.png) [@mveerman](https://www.ruby-forum.com/u/mveerman)\
**Post date:** [January 15, 2007, 5:11pm UTC](https://www.ruby-forum.com/t/model-question/81829/3 "2007-01-15T17:11:06Z")

</div>

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 = Contact.new  
> > d = Donor.new  
> > d.contact = c  
> > d.save  
> > c.donor\_id  
> > =\> 1
> 
> > Donor.find(1, :include =\> :contact)

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

---

<div class="post-metadata">

**Author:** ![mveerman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c57346/32.png) [@mveerman](https://www.ruby-forum.com/u/mveerman)\
**Post date:** [January 15, 2007, 5:14pm UTC](https://www.ruby-forum.com/t/model-question/81829/4 "2007-01-15T17:14:07Z")

</div>

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,  
thanks!

---

<div class="post-metadata">

**Author:** ![mveerman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c57346/32.png) [@mveerman](https://www.ruby-forum.com/u/mveerman)\
**Post date:** [January 15, 2007, 5:50pm UTC](https://www.ruby-forum.com/t/model-question/81829/5 "2007-01-15T17:50:15Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mveerman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/c57346/32.png) [@mveerman](https://www.ruby-forum.com/u/mveerman)\
**Post date:** [January 15, 2007, 5:57pm UTC](https://www.ruby-forum.com/t/model-question/81829/6 "2007-01-15T17:57:42Z")

</div>

mveerman wrote:

> 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,  
> thanks!

You could also look into either using Single Table Inheritence (STI) as  
the fan out of the subclasses isn’t too high, or use a polymorphic  
association.
