Forum: Ruby on Rails Representing relationships between model objects

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
SB (Guest)
on 2006-02-26 20:21
(Received via mailing list)
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
Francois B. (Guest)
on 2006-02-27 03:54
(Received via mailing list)
Hi !

2006/2/26, SB <removed_email_address@domain.invalid>:
> 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 !
SB (Guest)
on 2006-02-27 04:15
(Received via mailing list)
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
Josh S. (Guest)
on 2006-02-27 04:38
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/HowToCreat...

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
This topic is locked and can not be replied to.