Rails中同一类对象之间关联的命名约定

时间:2012-07-03 16:40:02

标签: ruby-on-rails ruby-on-rails-3

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

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

问题:Rails中是否有针对此命名问题的约定?

2 个答案:

答案 0 :(得分:1)

使用userfriend这个主题有railscasts tutorial这似乎是合理的。它也支持互惠关系。

答案 1 :(得分: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]