6

我不太确定如何表达这一点,但是有没有一种好方法来实现一个列本质上可以互换的表?

示例:您有一个用户模型,并希望允许两个用户成为“朋友”。对我来说,显而易见的方法是创建一个包含两列(“friend1”和“friend2”)的表,每列都包含用户的密钥。这使得说“是 user1 和 user2 的朋友”之类的话很尴尬,因为您必须检查“(friend1=user1 ANDfriend2=user2) OR (friend1=user2 ANDfriend2=user1)”。它会起作用,但对我来说似乎很尴尬,每次您想从该表中获取某些内容时,您都在查看两列。有没有更优雅的方式来做到这一点?

4

3 回答 3

4

建立友谊关系时的一个关键选择是确定它是否是双向的。Twitter 以下是单向友谊和 Facebook 友谊是双向的示例。听起来你致力于双向,所以你有两个选择:

1)检查两个方向

select *
from friendships 
where (friend1 = 123 and friend2 = 456) OR (friend2 = 123 and friend1 = 456)

2) 总是将较低的user_id 放入friend1,较高的user_id 放入friend2,那么您的测试只需要检查一个方向。这有点难以维护,所以我只会出于性能原因才这样做。

于 2013-02-28T19:31:23.060 回答
1

实现这一点的方式可能看起来有点尴尬。这个想法是在一个有两列的表中有一个“friendshipId”:friendshipId 和 user。现在用户可以互换。

要确定 user1 和 user2 是否是朋友:

select friendshipId
from friends
group by friendshipId
having sum(case when name = user1 then 1 else 0 end) > 0 and
       sum(case when name = user2 then 1 else 0 end) > 0

明智地使用约束、触发器和存储过程将确保朋友关系只有两个用户,某人不能自己成为朋友,等等。

于 2013-02-28T19:16:49.717 回答
0

您可以通过 has_many 或 has_and_belongs_to_many http://guides.rubyonrails.org/association_basics.html

任何你想要一个链接你的用户模型的连接表。

例如

class User < ActiveRecord::Base
  has_many :followings
  has_many :followers, :through => :followings, :class_name => "User"
  has_many :followees, :through => :followings, :class_name => "User"
end


class Following < ActiveRecord::Base 
  # fields: follower_id followee_id (person being followed)
  belongs_to :follower, :class_name => "User"
  belongs_to :followee, :class_name => "User"
end

就像用户有很多:用户一样,还是我必须使用另一种方式来建立基于朋友的社交网络?

于 2013-02-28T19:36:32.920 回答