在这种情况下,我通常会标准化数据。
class User
has_many :friendships
has_many :friends
end
class Friendship
belongs_to :user
belongs_to :friend, :class_name => "User"
after_create :reciprocate_friendship
def reciprocate_friendship
return if friend.friends.exists?(user) # do nothing if reciprocal friendship exists
friend.friends << user
end
end
这样您就可以优化朋友查询。
编辑
如果您必须将朋友关系存储在一行中,则向User
模型添加一个附加关联:
has_many :network_friends, :class_name => "User", :finder_sql => Proc.new {
%Q{
SELECT * FROM users
JOIN friendships
ON (users.id = friendships.user_id OR users.id = friendships.friend_id)
WHERE users.id = #{id}
}
}
现在您可以按如下方式使用新关联:
user1.friends << user2
user3.friends << user1
user1.network_friends # [ user2, user3]