[newbie] Symmetric relationships

This is my first shot at using Rails… How does one establish symmetric
relationships? I’m building a web application where family
relationships between members is useful to know. I’m not sure how to
get the joins to work though…

I have a table of Members and I want to capture, for example, spousal
relationships. The problem I’m running into is that both sides of the
relationship will point back to the ‘members’ table, but must have
different column names.

class CreateRelationships < ActiveRecord::Migration
def self.up
create_table :relationships do |t|
t.column :member_id, :integer
t.column :member2_id, :integer
#preset tags such as “spousal”, “parental”, “other”
t.column :type, :string, :limit => 15
#type to be used for “other”
t.column :type_for_other, :string, :limit => 50
end
end

def self.down
drop_table :relationships
end
end

Using a ‘has_many :relations, :through => :relationships’ link seems
appropriate, but I’m not sure how to key it to both columns.

class Member < ActiveRecord::Base
has_many :relations, :through => :relationships
end

Is this a job for the :source attribute?

On 10/8/06, AnalogKid [email protected] wrote:

different column names.
end

I think the proper way of modelling this kind of relationship is to have
two
entries in the Relationships table. Otherwise, the semantics of the
fields
change depending on which way you are looking at the relationship.

So rather than having mem,ber and member2, you would have
relationship_owner
and related_person, where your model class should take care of creating
both
relationship entries in a add_relationship method or similar. This will
also
make your queries a lot easier. For example, for a father/son
relationship,
you will have:

relationship_owner related_person relationship
Daddy Bob Little Joe Son
Little Joe Daddy Bob Father

When you are querying for everybody who is a son, you only need to look
for
a “Son” relationship, rather than having endless conditions on
(member=some_id and relationship=‘Son’) OR (member_2=some_id and
relationship=‘Father’)

Cheers,
Max

I’m facing a similar problem except that any given individual can have
many
relationships. For example, Daddy Bob may be Little Joe’s father. At the
same time, he might also be Suzy Q’s husband and Little O. Annie’s
employer.

How would you model that kind of networked relationship?

(sorry to hijack this thread, but I’m guessing this is an issue others
may
have as well.)

Max M.-3 wrote:

relationship entries in a add_relationship method or similar. This will
for
a “Son” relationship, rather than having endless conditions on
(member=some_id and relationship=‘Son’) OR (member_2=some_id and
relationship=‘Father’)


View this message in context:
http://www.nabble.com/-newbie--Symmetric-relationships-tf2403812.html#a6711119
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

On 10/9/06, s.ross [email protected] wrote:

(sorry to hijack this thread, but I’m guessing this is an issue others may
have as well.)

>

This layout for a relationship table models a many-to-many relationship
between entries for people. There hsould not be anything else you need
to
do, except add more rows:

relationship_owner related_person relationship
Daddy Bob Little Joe Son
Little Joe Daddy Bob Father
Daddy Bob Annie Wife
Annie Daddy Bob Husband

Just make sure that your model creteas the appropriate reverse
relationship,
for example:

class Person < ActiveRecord::Base

reverse_relationships = [
:Child=>:Parent,
:Parent=>:Child,
:Husband=>:Wife,
:Wife=>Husband,
:Employer=>Employee,
:Employee=>Employer
]

def relate_to(person, relationship)
r1 = Relationship.create do |r|
r.owner = this
r.related_person = person
r.relationship = relationship
end

r2 = Relationship.create do |r|
   r.owner = person
   r.related_person = this
   r.relationship = reverse_relationships[relationship.intern].to_s
end

end

end

Note that this does not make a distinction between Son/Daughter or
Mother/Father.

If you have your has_many :through set up right, you can then use
Person.find(1).relationships.

You can even use association extensions:

has_many :related_people, :through=>:relationship do
def relation(type_of_relationship)
find(:all, :conditions=>[ ‘relationship_type=?’,
type_of_relationship ]
end
end

You can then do:

dad = Person.find(1)
children = dad.related_people.relation(‘Child’)

As the association extension automatically sets the scope to the parent
relationship (parent and relationship here are in relational database
terms).

Cheers,
Max

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs