I have a question on how to approach a simple self-referencing data model in Rails: I have a table called "relationships": create_table :relationships do |t| t.integer :user_id t.integer :is_relationship_with t.string :relationship t.timestamps end And a table called "user" create_table "users", :force => true do |t| t.column :login, :string t.column :email, :string #... and so on... end A relationship could be one of the following: friend_of, student_of, parent_of. Any user should be able to have one or more of these, but of course should be defined only once as one of these three options. My question is, how would I do this in the model? I am assuming it would go into my model/relationships.rb file using something like a has_and_belongs_to_many instruction, but not sure how that should look given the recursive nature of this data model. Any strategic advice would be most appreciated! Cheers, Joe --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Apr 25, 11:25 am, Joe Lewis <joele...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> A relationship could be one of the following: friend_of, student_of, > parent_of. Any user should be able to have one or more of these, but > of course should be defined only once as one of these three options.Just a correction: Any user could have any number of such relationships. (Started this question out using my Roles model where that would have made more sense...) And to further clarify my Relationships data: t.integer :user_id # is the obvious foreign key back to the user table. t.integer :is_relationship # is the foreign key back to the user table for whom this relationship is being applied. (name changed slightly from earlier post) t.string :relationship # can be friend_of, student_of, parent_of. replaces the _relationship_ part of the above field. I can see in my relationships.rb model that this might be a start: class Relationship < ActiveRecord::Base has_many :users, :through => :relationships end But I''m confused about what to do about the :is_relationship part, and in turn what I would need to put in the user model - has_many :relationships ? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I was just looking for a solution to this myself! I didn''t find one so I had a play, and came up with the following example. It all seemed to work quite nicely so I thought I''d post it Overview --------------------------------------- I''ve used a twitter metaphor with users, followers, and leaders: I have 2 classes, one called "User", and one called "UserFollower" which is basically a self referential linking table. In the user_followers table there is two foreign keys - user_id and follower_id Code --------------------------------------- class User < ActiveRecord::Base has_many :user_followers has_many :followers, :through => :user_followers has_many :user_leaders, :class_name => "UserFollower", :foreign_key => "follower_id" has_many :leaders, :through => :user_leaders, :source => :user end class UserFollower < ActiveRecord::Base belongs_to :user belongs_to :follower, :class_name => "User" end Console Session --------------------------------------->> user = User.create( :name => "Jono" )=> #<User id: 1, name: "Jono", created_at: "2008-04-29 15:33:02", updated_at: "2008-04-29 15:33:02">>> User.create( :name => "David" )=> #<User id: 2, name: "David", created_at: "2008-04-29 15:33:13", updated_at: "2008-04-29 15:33:13">>> user.followers=> []>> user.user_followers.create( :follower => User.find(2) )=> #<UserFollower id: 1, user_id: 1, follower_id: 2, created_at: "2008-04-29 15:34:25", updated_at: "2008-04-29 15:34:25">>> user.followers=> [#<User id: 2, name: "David", created_at: "2008-04-29 15:33:13", updated_at: "2008-04-29 15:33:13">]>> user = User.find(2)=> #<User id: 2, name: "David", created_at: "2008-04-29 15:33:13", updated_at: "2008-04-29 15:33:13">>> user.followers=> []>> user.leaders=> [#<User id: 1, name: "Jono", created_at: "2008-04-29 15:33:02", updated_at: "2008-04-29 15:33:02">] On Apr 26, 7:47 am, Joe Lewis <joele...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Apr 25, 11:25 am, Joe Lewis <joele...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > A relationship could be one of the following: friend_of, student_of, > > parent_of. Any user should be able to have one or more of these, but > > of course should be defined only once as one of these three options. > > Just a correction: Any user could have any number of such > relationships. (Started this question out using my Rolesmodelwhere > that would have made more sense...) > > And to further clarify my Relationships data: > > t.integer :user_id # is the obvious foreign key back to the user > table. > t.integer :is_relationship # is the foreign key back to the user table > for whom this relationship is being applied. (name changed slightly > from earlier post) > t.string :relationship # can be friend_of, student_of, parent_of. > replaces the _relationship_ part of the above field. > > I can see in my relationships.rbmodelthat this might be a start: > > class Relationship < ActiveRecord::Base > has_many :users, :through => :relationships > end > > But I''m confused about what to do about the :is_relationship part, and > in turn what I would need to put in the usermodel- > has_many :relationships ?--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I''ve written a tutorial on this now because it''s such a frequently asked question: http://frozenplague.net/2008/04/29/self-referrential-relationships/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---