Topic: New to rails, not sure how to model this

Well, as in the title, I'm pretty new to rails, though I've been messing around with it on and off for a few months. nothing big, just some test projects with everything pretty simple.

Well, right now I'm trying to put something together and I'm having trouble conceptualizing just how to model things. I'm putting together what basically amounts to a family tree - I have people, and I have relationships between people (ie, a father may have a daughter or two and a wife). I've tried person has_many :relationships and relationship belongs_to :person, but that seemed to just confuse me and my app. Likewise, I had trouble putting together a coherent db schema, as a relationships table would need two different person_id's (continuing the example, a relationship would have one id for the father, and one for his daughter).

With this app, I would need to be able to, when pulling a page up about a certain person, have links with names to those people that the person has relationships with.

Any suggestions? Thanks in advance.

EDIT: I'd just like to expand a little on this as well. I know it complicates things a bit, but I'd like to be able to have both a Father and a Mother branch down to the same Children (as tends to happen in families wink. Advice is appreciated.

Last edited by el.phantasmo (2006-11-16 01:59:47)

Re: New to rails, not sure how to model this

The only information common to every person is that everyone has a biological mother and father (unless they are a clone I suppose, but then you could use the same person as both mother and father). I would start with Person model, and in your database have a mother_id and father_id. These point to other people in the database. To find someone's siblings you could do a search for people with the same mother and father. I also am unsure how you would model this. Perhaps you could subclass the Person model to make a mother and father model, where each would validate their respective sexes.

Re: New to rails, not sure how to model this

No need to subclass. You can do this:

class Person < ActiveRecord::Base
  belongs_to :mother, :class_name => 'Person', :foreign_key => 'mother_id'
  belongs_to :father, :class_name => 'Person', :foreign_key => 'father_id'
end

There's another thread a while ago on this forum that goes in further detail (fetching children, etc.)

Railscasts - Free Ruby on Rails Screencasts

Re: New to rails, not sure how to model this

You may want to subclass Person into Male and Female, because then you'll be able to identify things easier.

class Person < ActiveRecord::Base
  belongs_to :mother, :class_name => 'Female', :foreign_key => 'mother_id'
  belongs_to :father, :class_name => 'Male', :foreign_key => 'father_id'
end
class Male < Person
end
class Female < Person
end

This would allow you to do things like search for uncles, etc.  It would also give you some error-checking because it would be harder to assign a man as somebody's mother.

Re: New to rails, not sure how to model this

I don't know. To me subclassing adds a layer of complexity here that probably isn't necessary. This will make the class of the person change depending on how you access it. For example:

@person.father.class # => Male
Person.find(@person.father.id).class # => Person

If you are subclassing, I would go all out and do Single Table Inheritance. This way the class won't change depending on how it is fetched.

Last edited by ryanb (2006-11-16 15:08:11)

Railscasts - Free Ruby on Rails Screencasts

Re: New to rails, not sure how to model this

ryanb wrote:

No need to subclass. You can do this:

class Person < ActiveRecord::Base
  belongs_to :mother, :class_name => 'Person', :foreign_key => 'mother_id'
  belongs_to :father, :class_name => 'Person', :foreign_key => 'father_id'
end

There's another thread a while ago on this forum that goes in further detail (fetching children, etc.)

Ok, I'm interested in this too. In this case, this is something like this?

id       name        mother_id           father_id
---------------------------------------------------
1        Bill        2                   3
2        Sue         NULL                NULL
3        Rich        NULL                NULL

and ...

p = Person.find(1)
dad = p.father
dad.class  #  Person
dad.id     #  3
dad.father # nil

ok, but what about say a Myspace-style friends list? One person can have X number of friends, and the Person and all the friends are of the same class Person. Does that mean a people table, a people_people relations table, and then the Person class has

class Person Person < ActiveRecord::Base
    has_and_belongs_to_many :people
end

p = Person.find(1)
friends = p.friends
friends[0].class   # Person
...

In this case, how do you prevent someone being friends with them self?

Last edited by tortoise (2006-11-16 16:06:51)

Re: New to rails, not sure how to model this

I would create a friendships table with person_id and friend_id columns in it. You can then set up the association like this:

class Person < ActiveRecord::Base
  has_many :friendships
  has_many :friends, :through => :friendships # you may need to customize this a bit
end

class Friendship < ActiveRecord::Base
  belongs_to :person
  belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id'
end


You can prevent someone from being a friend of himself through validation.

# in friendship model
def validate
  errors.add_to_base('Cannot add yourself as a friend.') if person_id == friend_id
end

Railscasts - Free Ruby on Rails Screencasts

Re: New to rails, not sure how to model this

ryanb wrote:

No need to subclass. You can do this:

class Person < ActiveRecord::Base
  belongs_to :mother, :class_name => 'Person', :foreign_key => 'mother_id'
  belongs_to :father, :class_name => 'Person', :foreign_key => 'father_id'
end

There's another thread a while ago on this forum that goes in further detail (fetching children, etc.)

Thanks a bunch, exactly what I needed! Found the thread (http://railsforum.com/viewtopic.php?id=886) and it was a big help as well.