我不太确定如何表达这一点,但有没有一种很好的方法来实现一个表格,其中列基本上是可以互换的?
示例:您有一个用户模型,并希望允许两个用户成为“朋友”。对我来说,显而易见的方法是拥有一个包含两列('friend1'和'friend2')的表,每个列包含一个User的键。因为你必须检查“(friend1 = user1 AND friend2 = user2)OR(friend1 = user2 AND friend2 = user1)”,这使得说“是user1和user2朋友”之类的东西很尴尬。它会起作用,但对我来说这似乎很尴尬,每当你想要从那张桌子上得到一些东西时,你就会看到两个列。这样做有更优雅的方式吗?
答案 0 :(得分:3)
建立友谊关系时的关键选择是决定它是否是双向的。推特之后是一个定向友谊和Facebook友谊双向的例子。听起来你已经致力于双向,所以你有两个选择:
1)检查两个方向
select *
from friendships
where (friend1 = 123 and friend2 = 456) OR (friend2 = 123 and friend1 = 456)
2)始终将较低的user_id放入friend1,将较高的user_id放入friend2,然后您的测试只需检查一个方向。这有点难以维护,所以我只是因为性能原因而需要它。
答案 1 :(得分: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
明智地使用约束,触发器和存储过程将确保朋友关系只有两个用户,有人不能自己交友,等等。
答案 2 :(得分:0)
您可以执行has_many through或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
与user has many :users, or must I use another way for a friend based social network?
相同