Ruby on rails RubyonRails:是否可以:包括循环联接表的另一个分支?

Ruby on rails RubyonRails:是否可以:包括循环联接表的另一个分支?,ruby-on-rails,activerecord,find,named-scope,find-by-sql,Ruby On Rails,Activerecord,Find,Named Scope,Find By Sql,我正在开发一个模拟用户之间友谊的应用程序 class User has_many :friendships has_many :friends, :through => :friendships, :conditions => "status = #{Friendship::FULL}" end class Friendship belongs_to :user belongs_to :friend, :class_nam

我正在开发一个模拟用户之间友谊的应用程序

class User
  has_many :friendships
  has_many :friends, 
           :through => :friendships,
           :conditions => "status = #{Friendship::FULL}"
end
class Friendship
  belongs_to :user
  belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
end
当两个用户成为朋友时,将创建友谊类的两个实例,一个用于友谊的每个方向。这是必要的,因为可以在每个方向上设置不同的权限,也为了便于查找,所以我们总是按用户id进行搜索,而无需创建第二个索引,也无需加倍搜索

有没有可能,使用find或命名作用域将一个朋友和反友谊一起拉出来?我之所以这样做是因为我允许用户编辑存储在他们自己的友谊分支中的友谊权限,因此当我向用户显示朋友的信息时,我需要检查另一分支以查看权限的设置。(顺便说一句,这似乎是一种合乎逻辑的做事方式吗?要么你把东西放在另一边,要么你必须在展示前咨询另一边,两者都有点不愉快。)

我已经成功地创建了一批SQL来完成这项工作:

def self.secure_friends(user_id)
  User.find_by_sql("SELECT u.*, cf.permissions
                    FROM users u 
                    INNER JOIN friendships f ON u.id = f.friend_id 
                    INNER JOIN friendships cf ON u.id = cf.user_id AND cf.friend_id = #{user_id} 
                    WHERE ((f.user_id = #{user_id}) AND (f.status = #{Friendship::FULL}))")
end

该函数返回用户的所有好友姓名和ID以及权限。但是,这似乎并不理想,这意味着我必须通过调用friend.permissions来访问权限,其中权限实际上不是friend的成员,而是通过find\u by\u sql作为属性合并进来的。总而言之,我更愿意使用命名的作用域或find调用来实现这一点,但不幸的是,我使用这种方法的每次尝试都会导致错误,因为Rails无法将相同的友谊联接表联接到查询中两次。

我不确定您想做多少,你会允许一个插件做多少事情——但我用过这个插件,它有很多朋友成功地使用了这个插件:

你可以看看来源和灵感。。。只需要一个友谊模型,它包含以下内容:

belongs_to :friendshipped_by_me,   :foreign_key => "user_id",   :class_name => "User"
belongs_to :friendshipped_for_me,  :foreign_key => "friend_id", :class_name => "User"
然后,在您的用户类中,有:

has_many :friends_by_me,
         :through => :friendships_by_me,
         :source => :friendshipped_for_me
或者,只是

/app/models/user

has_many_friends
后来:

@current_user.friends.each{|friend| friend.annoy!}