Has_many and bi-directional relationships

I’m working on an app with a friend type system. I currently have
setup like this with 2 tables.

users table keeps track of users

user_relationships table keeps track of friendships. Now, there
should be two rows for each relationship. This is to keep track of
the directional nature of the relationship between users. Each time a
relationship is made, both rows should be inserted into the table.

user_1 user_2 data
user_2 user_1 data

So what I can’t decide is what is the best way to implement these in
my rails app to be able to create a view of all user_relationships
with a given userid.

I can define a Relationship class, and mark User with has_many. But
that will only select the relationships based on one column right? So
it would look in one column and find all rows from that column. so if
I call User.relationships I will only have half of the relationship
info right?

So what I think i’m looking for is a way to overload the
User.relationships so that I can return a list of Relationships that I
compiled by making two queries, one on each column?

I can think of some other options that might work in this instance
(since i know there is always two rows of data I can just query on 1
column, and then in the Relationship model handle the dual column
nature of info), but I think it would still be interesting to know how
to overload the function, or describe this behavior better in my
model.

I hope this makes sense

Thanks

pipplo wrote:

I’m working on an app with a friend type system. I currently have
setup like this with 2 tables.

users table keeps track of users

user_relationships table keeps track of friendships. Now, there
should be two rows for each relationship. This is to keep track of
the directional nature of the relationship between users. Each time a
relationship is made, both rows should be inserted into the table.

user_1 user_2 data
user_2 user_1 data
[…]

That’s not necessarily a great idea. Please see
Creating reflective has_and_belongs_to - Rails - Ruby-Forum .

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

How about something like this:

class User < ActiveRecord::Base
has_many :relations, :foreign_key => “from_user”
end

class Relation < ActiveRecord::Base
belongs_to :from_user, :class_name => “User”, :foreign_key =>
“from_user”
belongs_to :to_user, :class_name => “User”, :foreign_key => “to_user”
end

To print list of all friends of , say, first user ind DB, you can
something
like this:

User.first.relations.all.each { |r| puts r.to_user.name }

Here is Migrations for two tables:

class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.timestamps
end
end

def self.down
drop_table :users
end
end

class CreateRelations < ActiveRecord::Migration
def self.up
create_table :relations do |t|
t.integer :from_user
t.integer :to_user
# other data specific to relation
t.timestamps
end
end

def self.down
drop_table :relations
end
end


It may have some gotchas, but can be enhanced.

On Thu, Sep 16, 2010 at 11:17 PM, Marnen Laibow-Koser

its done here