Rails - 双向“友谊”模式(续)

时间:2009-07-01 19:54:00

标签: ruby-on-rails ruby

这是这个问题的延续: Original Question (SO)

这个问题的答案涉及以下一组模型:

class User < ActiveRecord::Base
  has_many :friendships
  has_many :friends, :through => :friendships #...
end

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => 'User', :foreign_key => 'friend_id'
end 

<% for friendship in @user.friendships %>
  <%= friendship.status %>
  <%= friendship.friend.firstname %>
<% end %>

这样可以正常工作,如果说,我有一个用户,我希望得到他或她的id为友谊模型的所有“友谊”:user_id FK。但是,当我运行类似

的东西时
@user.friendships.friends

我希望它返回用户所属的所有用户记录:用户或友谊中的:朋友 - 换句话说,返回该用户所涉及的所有友谊。

希望以上是有道理的。我仍然对rails非常陌生,并希望有一种方法可以优雅地完成这项工作,而无需仅使用标准链接表或提供自定义SQL。

谢谢!

汤姆

4 个答案:

答案 0 :(得分:7)

关于此主题的

railscasts episode

答案 1 :(得分:3)

你不能只在这里使用@ user.friendships,因为它只会给你那些@ friendship.user_id == @ user.id的友谊。 我现在唯一能想到的就是做

Friendship.find_by_user_id(@user.id).concat Friendship.find_by_friend_id(@user.id)

答案 2 :(得分:2)

我的解决方案是范围:

# model
class Message < ActiveRecord::Base
  belongs_to :sender, :class_name => "User"
  belongs_to :recipient, :class_name => "User"

  scope :of_user, lambda { |user_id| where("sender_id = ? or recipient_id = ?",
        user_id,  user_id) }
end


# in controller
@messages = Message.of_user(current_user)

答案 3 :(得分:1)

来自railscast链接:

# models/user.rb
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user