问题描述
我目前正在开发一个小型社交网络应用程序,现在我正在尝试创建一个模型来代表用户之间的友谊.这是我目前想到的:
I'm currently working on a small social networking application and right now I'm trying to create a model that represents friendships between users. This is what I came up with so far:
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 作为布尔值,我想使用它将友谊定义为待定或已确认.
My friendship model has a field confirmed as boolean which I'd like to useto define a friendship as pending or confirmed.
如何访问某个用户的所有待处理请求?我可以以某种方式定义这使用 Rails 的 scope 方法?类似的东西
How can I access all pending request for a certain user? Can I somehow definethis using Rails' scope method? Something like
current_user.friendships.requests # => [Friendship, Friendship, ...]
会很棒.
如何使这种关联双向化?我是否只需添加另一个友谊一旦有人确认了一个朋友请求,这样我的友谊表格看起来类似于:
How can I make this association bidirectional? Do I simply add anotherfriendship once one has confirmed a friend request such that my friendshiptable would look similar to this:
| user_id | friend_id | confirmed |
-----------------------------------
| 1 | 2 | true |
| 2 | 1 | true |
推荐答案
要访问所有待处理的好友,您可以使用关联:
To access all pending friendships you can use an association:
has_many :pending_friends,
:through => :friendships,
:source => :friend,
:conditions => "confirmed = 0" # assuming 0 means 'pending'
要使友谊双向,您可能需要将布尔 confirmed 列替换为具有以下三个值之一的字符串 status 列:'pending'、'requested' 和 'accepted'(可选'rejected').这将有助于跟踪谁提出了好友请求.
To make the friendship bidirectional, you may want to replace your boolean confirmed column with a string status column that has one of the following three values: 'pending', 'requested' and 'accepted' (optionally 'rejected'). This will help keep track of who made the friendship request.
当一个好友请求被发送时(比如从 Foo 到 Bar),你创建了两个好友记录(封装在一个交易中):一个是请求的,一个是挂起的以反映响应.Bar 已请求 Foo 建立友谊,而 Foo 与 Bar 有待处理的友谊.
When a friendship request is sent (say from Foo to Bar), you create two friendship records (encapsulated in a transaction): one requested and one pending to reflect resp. that Bar has a requested friendship from Foo and Foo has a pending friendship with 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),两个友谊记录都被设置为接受.
When the friendship is accepted (e.g. by Bar), both friendship records are set to accepted.
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 章中有大量介绍.这是源代码,它应该可以帮助您完善您的解决方案.
This is largely covered in chapter 14 of the Railspace book by Michael Hartl and Aurelius Prochazka. Here's the source code which should help you refine your solution.
这篇关于如何在 Rails 3 中为社交网络应用程序实现友谊模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!