Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
919 views
in Technique[技术] by (71.8m points)

ruby - How to model a mutual friendship in Rails

I know this question has been asked before on Stack Overflow, but the answers aren't doing it for me in ways I can explain. My general approach was inspired by this tutorial.

What I'm trying to do, is create a really simple model for friending users that creates an equivalent friendship on both ends with a single record.

At the db level, I just have a 'friendships' table that just has a user_id, a friend_id, and an is_pending boolean column.

In user.rb I've defined the relationship as:

has_many :friendships
has_many :friends, through: :friendships

In friendship.rb, I've defined the relationship as:

belongs_to :user
belongs_to :friend, :class_name => 'User'

If I add a friendship, I can access as follows:

> a = User.first
> b = User.last
> Friendship.new(a.id, b.id)
> a.friends
=> #<User b>

That's perfect, but what I want is to also be able to go in the other direction like so:

> b.friends

Unfortunately, with the relationship defined as it is, I get an empty collection. The SQL that runs shows that it's searching for user_id = b.id. How do I specify that it should also search for friend_id = b.id?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Maybe this:

friendship.rb
belongs_to :friend_one, :foreign_key => :user_id
belongs_to :friend_two, :foreign_key => :friendship_id

and

user.rb

has_many :friendship_ones, :class_name => 'Friendship', :foreign_key => :friendship_id
has_many :friend_ones, through: :friendship_ones
has_many :friendship_twos, :class_name => 'Friendship', :foreign_key => :user_id
has_many :friend_twos, through: :friendship_twos


def friends
  friend_ones + friend_twos
end

You get two queries to find the friends, but it is a simple data model and you you do just call @user.friends to find the instances.

It would be amenable to eager loading, if you load the two friend_ones and friend_twos associations.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...