Representing relationships between model objects

I’m a little stumped on how to approach the subject of representing
relationships between a single model object.

Basically, I want a User to be able to mark others as Friends,
Contacts, etc. The caveat is that User A can mark User B as a Friend
but that doesn’t mean User A is marked as a friend by User B. It can
either be a one-way relationship or two-way relationship.

Right now I’m confused as to whether there is a “proper” way to do
this. I’m looking at Single Table Inheritance, HABTM, and now the new
Polymorphic Associations in Edge Rails.

The main thing that’s confusing me is that when marking someone as
Friend, you will have to reference the “user_id” of both User A and
User B with a foreign key, but I don’t know how to sort that out.

Sorry if this question is vague but my understanding of accomplishing
this in rails is even vaguer. However, most of the examples I see
involve defining relationships between two different models such as
Products, LineItems, and Orders or something like that.

Sam

Hi !

2006/2/26, SB [email protected]:

Basically, I want a User to be able to mark others as Friends,
Contacts, etc. The caveat is that User A can mark User B as a Friend
but that doesn’t mean User A is marked as a friend by User B. It can
either be a one-way relationship or two-way relationship.

I would go with a HABTM relationship, but with a full model in the
middle.

class User < ActiveRecord::Base
has_many :relationships

def make_friend_of!(name)
target = User.find_by_name(name)
raise “No person by that name” unless target

self.relationships.create(:target => target)

end
end

class Relationship
belongs_to :target
end

user = User.new(:name => ‘Francois’)
user.make_friend_of!(‘John’)

That’s the way I would implement it. Of course, I don’t know all your
requirements, so I can’t really say it is the best way.

Hope that helps !

That’s similar to what I was thinking but then I don’t understand how
you can map clarify that one User is the owner of the relationship and
the other User is classified under the relationship because linking
them by foreign_key, they would both be “user_id”.

After sleeping on it, I’m thinking of going with two Single Table
Inheritances. One is Friends and Another is Groups. Friends will
have various “types” and each User can aggregate their Friends in
Groups. It would function as a “join table” but allow more features.
That way I can model one way relationships.

Such as:
John => Mary’s Friend
Mary => John’s Contact

Polymorphic Associations look promising but I’ll need to see more
documentation before I can even explore it as an option.

Thanks for the response!
Sam

You can do this in several ways. The trick is that you can tell Rails to
use a different name for the field instead of the default one based on
the model class. That will support one-way relationships, or two-way if
you make links in both directions There is a good description of how to
do that at the bottom of this wiki page:
http://wiki.rubyonrails.org/rails/pages/HowToCreateASelfReferentialManyToManyRelationship

If you are brave enough to try Edge Rails, you can do something similar
with the has_many :through association, otherwise known as join models.
This is probably the way to go if you want to pursue your open-ended set
of relationship types. The schema-safe way to do that is to set up a
3-way join between user1, user2, and call it a role. The role table
would have a name and maybe other fields that describe things about the
relationship. That way you can add new roles to the app without having
to create a new model class or modify the schema. Hmm, I should
probably write something up about how to do this with some code
examples.

–josh

SB wrote:

That’s similar to what I was thinking but then I don’t understand how
you can map clarify that one User is the owner of the relationship and
the other User is classified under the relationship because linking
them by foreign_key, they would both be “user_id”.

After sleeping on it, I’m thinking of going with two Single Table
Inheritances. One is Friends and Another is Groups. Friends will
have various “types” and each User can aggregate their Friends in
Groups. It would function as a “join table” but allow more features.
That way I can model one way relationships.

Such as:
John => Mary’s Friend
Mary => John’s Contact

Polymorphic Associations look promising but I’ll need to see more
documentation before I can even explore it as an option.

Thanks for the response!
Sam