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

Posted

技术标签:

【中文标题】如何在 Rails 3 中为社交网络应用程序实现友谊模型?【英文标题】:How to Implement a Friendship Model in Rails 3 for a Social Networking Application? 【发布时间】:2011-08-02 12:49:21 【问题描述】:

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

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

我的 friendship 模型有一个字段 confirmed 作为我想使用的布尔值 将友谊定义为未决或已确认。

如何访问某个用户的所有待处理请求?我可以以某种方式定义 这使用 Rails 的 scope 方法?类似的东西

current_user.friendships.requests # => [Friendship, Friendship, ...]

会很棒。

我怎样才能使这种关联是双向的?我是否只是添加另一个 友谊一旦有人确认了朋友请求,这样我的友谊 表看起来与此类似:

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

【问题讨论】:

朋友与其他用户的不同之处在于他们通过友谊联系在一起这一事实? 【参考方案1】:

要访问所有未决的友谊,您可以使用关联:

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

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

当发送友谊请求(例如从 Foo 到 Bar)时,您会创建两个友谊记录(封装在一个事务中):一个已请求,一个未决以反映相应的。 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

这在 Michael Hartl 和 Aurelius Prochazka 所著的 Railspace 书籍的第 14 章中有大量介绍。这是source code,它应该可以帮助您完善您的解决方案。

【讨论】:

只是说谢谢,你帮我解决了同样的问题,但在 php 中。 =) +1 您知道友谊模型中应该可以访问哪些属性吗?我假设只有状态属性应该是可访问的。我说的对吗? 嗨@mbreining我今天遇到了你的解决方案,我不知道是否真的有比这更强大的解决方案,但我认为创建两条线来建立关系并不是一个好主意Friendships 表中有 2 位用户,如果您能提供帮助,我会在这里发布一个新问题 ***.com/questions/19339596/… 谢谢您【参考方案2】:

终极参考:

http://railscasts.com/episodes/163-self-referential-association

【讨论】:

【参考方案3】:

简短的回答是肯定的。再做一条友谊记录来代表双向关联。

我为此类问题编写了一个名为 has_friendship 的 gem。您只需将has_friendship 放入您的模型中,所有关联和方法都会得到处理。

希望这会有所帮助!

【讨论】:

【参考方案4】:

阅读 this tutorial illustrating a relationship model 上的 Rails 教程。它应该正是您正在寻找的。​​p>

【讨论】:

【参考方案5】:

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

【讨论】:

您知道友谊模型中应该可以访问哪些属性吗?我假设只有状态属性应该是可访问的。我说的对吗?

以上是关于如何在 Rails 3 中为社交网络应用程序实现友谊模型?的主要内容,如果未能解决你的问题,请参考以下文章

Rails 中的社交网络风格通知系统

如何在 Rails 2.3.8 中为 https 请求(即安全连接)查找客户端 IP

Rails:如何在 Rails 中为 Devise 设置密钥?

如何在 Rails 3.1 中为 CoffeeScript 使用选项“--bare”?

Rails 社交网络友谊的最佳资源 [关闭]

如何在 Rails 中为 Mechanize 设置自定义用户代理