Confused about ActiveRecord relationships


#1

I am very confused about where to put the belongs_to and the has_one
(and other relationship identifiers). I have read the RDoc and the
agile book many times about this and I think i still see it backwards.
Let me outline my app so you have an understanding…

I have 2 tables:

Schools { id, school_name, address_id }

and

Addresses { street1, street2, city, state, zip, country }

*** this is the way that makes sense to me but it doesnt work ******
Models

school.rb
has_one :address

address.rb
belongs_to :school

View for School
<% for school in @schools %>

<%= school.school_name %>
<%= school.address.street1 %>
<% end %>

(I get an error referencing the school.address.street1)

*** this is the way that does not make sense but works ****
Models

school.rb
belongs_to :address

address.rb
has_one :school

View for School
<% for school in @schools %>

<%= school.school_name %>
<%= school.address.street1 %>
<% end %>

I could really use some help understanding how to create the
relationships, and how to access them properly in the views.


#2

Hello Nate,

and
belongs_to :school
[…]

(I get an error referencing the school.address.street1)

Put the foreign key in addresses table and not in schools table. So :

Schools { id, school_name }

Addresses { street1, street2, city, state, zip, country, school_id }

Keep your models as above and it should work.

Think 'belongs_to" as ‘refers_to’, then your addresses table needs
a key referencing to schools table.

HTH,

   -- Jean-François.

#3

Put the foreign key in addresses table and not in schools table. So :

Schools { id, school_name }

Addresses { street1, street2, city, state, zip, country, school_id }

Keep your models as above and it should work.

Think 'belongs_to" as ‘refers_to’, then your addresses table needs
a key referencing to schools table.

Jean-François,
thank you very much for your response.
what i didnt say earlier was that i am trying to use a single address
table as a child table for many different tables:

schools( id, school_name, address_id)
students(id, name, address_id)
exam(id, name, type_id, address_id)
and more…

so am i going to have to have to put belongs_to :address in each of the
models for those tables, and has_one :school, has_one :student, has_one
:exam in the address model; even though it doesnt make sense to me?


#4

Nate :

has_one :exam in the address model; even though it doesnt make
sense to me?

No, in fact you should polymorphic associations. The idea is to
use an interface to which your School, Student, Exam… models
will be associated. The Address model will be associated to
the interface. Read carefully the wiki pages related to
polymorphic associations :

http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations

And the example chosen is nearly the same as your issue !

You will have

class School < AR::B
has_one :address, as :addressable
end

and so on…

Good luck,

РJean-Fran̤ois.


#5

Jean-François, once again thanks for your help,

I understand how that works, and it sounds like that could work.
The problem i see is that the example assumes that you are using 1
address_id per row in the associated models; but what if i had a
customers table with a billing_address_id and a shipping_address_id?
I’m not just making these questions up, i do have a table that has that
situation.

Thank you,

Nate


#6

Josh’s blog entry may be helpful here.
http://blog.hasmanythrough.com/articles/2006/04/03/polymorphic-through
Have a read through that and give it a go.

Hope this helps,
-Nathan


#7

Jean-François wrote:

No, in fact you should polymorphic associations. The idea is to
use an interface to which your School, Student, Exam… models
will be associated. The Address model will be associated to
the interface. Read carefully the wiki pages related to
polymorphic associations :

http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations

And the example chosen is nearly the same as your issue !

You will have

class School < AR::B
has_one :address, as :addressable
end

I’m not convinced this is a good case for polymorphic associations.

Sounds like a simple case of multiple types with a belongs_to:
relationship with Address.

A simple foreign key is way faster than a compound foreign key, which
is essentially what polymorphic associations are.

Polymorphic associations definitely have their place. I’ve used the
same technique in the past (in WebObjects) for things like arbitrary
configuration objects and tagging.

Feel free to correct me. I’m new here.


#8

Hampton wrote:

To honestly answer this question, we’d have to have more information
than
just the snippet. There are several ways you could model this. Three
that I
can think of off the top of my head. Each has different strengths and
weaknesses. So, if you can describe to us the problem domain a bit more
clearly, we can help much better.

-hampton.

Hampton and all,
thanks again for this discussion and all of your advice,
let me give you a larger snippet (hopefully inclusive enough for this
example) so you can get a larger picture of the app.

Because I am still confused about which way to do this I will not put in
any of the model relationships I have thus far listed; I will just give
you the tables and allow you to see the referencing.

Tables:

Addresses
{ id, street1, street2, city, state_id, zip, county, country}

Professionals
{ id, name, email, fax, phone, birthday, social_security,
drivers_license_num}

Addresses_Professionals
{ id, address_id, professional_id, address_type_id, start_date,
end_date, public}

Address_types
{ id, type }

Clerkships
{ id, professional_id, facility_name, start_date, end_date, address_id,
school_id}

Licenses
{ id, professional_id, state_id, address_id, request_address_id,
license_number, license_status_id }

License_status
{ id, status }

Licensing_exams
{ id, professional_id, location, address_id, date}

I have about 15 other tables but this should encapsulate our objective
for this discussion.

After reading about polymorphic relationships and :through and still
being partially confused, I may just take the easy way and for each of
the models listed above add a belongs_to :address in it and it will
accomplish what I need. Is this a bad way of doing it?


#9

To honestly answer this question, we’d have to have more information
than
just the snippet. There are several ways you could model this. Three
that I
can think of off the top of my head. Each has different strengths and
weaknesses. So, if you can describe to us the problem domain a bit more
clearly, we can help much better.

-hampton.