0

我正在开发一个具有典型社交功能的应用程序:本质上,两个用户可以成为朋友。这是通过一个名为“Friendship”的关联类完成的,该类包含两个用户的 id。显然这两个键都不能称为“user_id”。正常的方法是为两个键赋予不同的名称并使其与 :class_name 一起使用。

问题是这种关系是完全互惠的,因为友谊不能只是一方面:它像 Facebook 一样运作,而不像 Twitter。我不想添加命名键“创建者”和“接受者”的信息,并且使用数字“user_1_id”或“user_2_id”听起来很糟糕。

问题:Rails 中有没有针对这个命名问题的约定?

4

2 回答 2

1

有一个关于这个主题的railscasts 教程user使用并且friend看起来很明智。它还支持互惠关系。

于 2012-07-03T16:46:32.383 回答
1

在这种情况下,我通常会标准化数据。

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]
于 2012-07-03T16:52:41.553 回答