如何在Rails 3中为社交网络应用程序实现友谊模型?

时间:2011-04-10 15:24:57

标签: ruby-on-rails ruby activerecord has-many-through

我目前正在开发一个小型社交网络应用程序,现在我正在尝试创建一个代表用户之间友谊的模型。这是我到目前为止所提出的:

class User < ActiveRecord::Base

  # ...
  has_many :friendships
  has_many :friends, :through => :friendships

end

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => 'User'
end

我的友谊模型有一个字段已确认为boolean我想使用 将友谊定义为待决或确认。

如何访问特定用户的所有待处理请求?我可以以某种方式定义 这使用Rails的范围方法?像

这样的东西
current_user.friendships.requests # => [Friendship, Friendship, ...]

会很棒。

如何将此关联设为双向?我只是添加另一个 友谊一旦确认了朋友请求,以便我的友谊 表看起来与此类似:

| user_id | friend_id | confirmed |
-----------------------------------
| 1       | 2         | true      |
| 2       | 1         | true      |

5 个答案:

答案 0 :(得分:30)

要访问所有待处理的友情,您可以使用关联:

has_many :pending_friends,
         :through => :friendships,
         :source => :friend,
         :conditions => "confirmed = 0"  # assuming 0 means 'pending'

要使友谊双向化,您可能希望将字符串 status 列替换为布尔已确认列,该列具有以下三个值之一:'pending', '已请求'和'已接受'(可选“已拒绝”)。这将有助于跟踪谁发出了友谊请求。

当发送友谊请求时(例如从Foo发送到Bar),您创建两个友谊记录(封装在事务中):一个请求,一个挂起以反映resp。 Bar与Foo和Foo有着友好的友谊,与Bar有着友好的关系。

  def self.request(user, friend)
    unless user == friend or Friendship.exists?(user, friend)
      transaction do
        create(:user => user, :friend => friend, :status => 'pending')
        create(:user => friend, :friend => user, :status => 'requested')
      end
    end
  end

当友谊被接受时(例如通过Bar),两个友谊记录都被设置为接受。

  def self.accept(user, friend)
    transaction do
      accepted_at = Time.now
      accept_one_side(user, friend, accepted_at)
      accept_one_side(friend, user, accepted_at)
    end
  end

  def self.accept_one_side(user, friend, accepted_at)
    request = find_by_user_id_and_friend_id(user, friend)
    request.status = 'accepted'
    request.accepted_at = accepted_at
    request.save!
  end

这一点在迈克尔·哈特尔和Aurelius Prochazka的“铁路空间”一书的第14章中有所论述。这是source code,它可以帮助您优化解决方案。

答案 1 :(得分:12)

答案 2 :(得分:3)

简短的回答是肯定的。只需制作另一张友谊记录即可表示双向关联。

我为这类问题写了一个名为has_friendship的宝石。您需要做的只是在模型中放入has_friendship,并且将处理所有关联和方法。

希望这有帮助!

答案 3 :(得分:2)

阅读关于Rails教程的this tutorial illustrating a relationship model。它应该是你正在寻找的。

答案 4 :(得分:1)

我向您推荐RailsS​​pace:构建社交网站。它清楚地解释了如何实现友谊模型。虽然它不能扩展到其他形式的关系,但非常适合你的问题。