01
Mar
12

Model mishaps

Mon-Weds this week I really felt the stretch.  I had dealt with models and creating associations before, but I had never cemented my knowledge of them to the degree that we did in boot camp.  Among the difficult ones were:

Self referential associations:  

Problem:  A family with each member represented as an instance of the Person model.  Each person will have a relationship (Relationship model) with other members of the family.  This seems to be an obvious has_many relationship, but the strange thing is that it is a has_many relationship with another member of the same class.  So it is not as easy as just saying has_many :people, :through => :relationships, because it is ambiguous which ‘person_id’ you is the ‘from’ and which is the ‘to’.


Solution:  You need to create your own names for these relationships, for example instead of saying has_many :people… you need to say something like has_many :person_tos.  But then rails doesnt know how to find your foreign key!  So you need to explicitly tell it where to find it.  has_many :person_to, :through => :relationships, :class_name => ‘Person’, :foreign_key => ‘person_to_id’. Then do the same with the other side of the relationship. has_many :person_from, :through => :relationships, :class_name => ‘Person’, :foreign_key => ‘person_from_id’  .  Then you need a model for the relationship which acts as a has many table.

This took me hours to figure out.  Some meta that I learned from Doug (thanks man), was that the syntax for doing this has changed somewhat in rails, and so it helps to sort out old blog posts that might talk about how to do it.  So narrowing the search to within the time period of the latest version of rails (which we are using), helps to hone in on the right syntax.

Using the #delegate method to access information

Problem:  There is a Person model, and a Details model which holds lots of information about the people represented in the people table.  How do you set up the association and how do you delegate?  At first glance, one might try this:

class Person < ActiveRecord::Base

has_one :details, :dependent => :destroy

delegate :name, :to => :details

after_initialize do

self.details.build

end

end

but, I ran into a problem where every time I created a person, then added details about that person, then went to check that detail through something like Person.last.details, I would find a completely empty and new instantiation of the details Model. 

Solution: as it turned out, calling Person.last runs the initialize function.  This was confusing to me because I interpreted that the initialize function would only be run when creating an object.  So, in the end, the solution was simply to check in the after_initialize function if the record is a new record or not and only create an association with a new detail object if it is a new record.

Although it was pretty frustrating at the time, I feel like I have learned a lot in the process of figuring out why I was having this difficulty, and I think I’m a better coder for having had this experience.  I hope these explanations helps people who ran into the same problems that I did.


0 Responses to “Model mishaps”



  1. Leave a Comment

Leave a comment