如何在Rails 3中为社交网络应用程序实现友谊模型?
我目前正在开发一个小型社交网络应用程序,现在我正在尝试创建一个代表用户之间友谊的模型。 这是我到目前为止提出的:
class User :friendships end class Friendship 'User' end
我的友谊模型有一个确认为布尔值的字段,我想用它来定义一个待定或确认的友谊。
如何访问特定用户的所有待处理请求? 我可以使用Rails的范围方法以某种方式定义它吗? 就像是
current_user.friendships.requests # => [Friendship, Friendship, ...]
会很好。
如何使这种关联双向化? 一旦确认了朋友请求,我就会添加另一个友谊,这样我的友谊表看起来就像这样:
| user_id | friend_id | confirmed | ----------------------------------- | 1 | 2 | true | | 2 | 1 | true |
要访问所有待处理的友谊,您可以使用关联:
has_many :pending_friends, :through => :friendships, :source => :friend, :conditions => "confirmed = 0" # assuming 0 means 'pending'
为了使友谊成为双向的,您可能希望将字符串状态列替换为具有以下三个值之一的字符串状态列:’pending’,’requested’和’accepted’(可选地’rejected’)。 这将有助于跟踪谁发出了友谊请求。
当发送友谊请求时(例如从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
迈克尔·哈特尔(Michael Hartl)和奥雷利乌斯·普罗哈兹卡(Aurelius Prochazka)在“铁路空间”一书的第14章中对此进 以下是可帮助您优化解决方案的源代码 。
简短的回答是肯定的。 只需创建另一个友谊记录即可表示双向关联。
我写了一个名为has_friendship的gem来解决这类问题。 您需要做的就是在模型中has_friendship
,并且将处理所有关联和方法。
希望这可以帮助!
阅读本教程,了解Rails教程中的关系模型 。 它应该是你正在寻找的。
我向您推荐RailsSpace:构建社交网站。 它清楚地解释了如何实现友谊模型。 虽然它不能扩展到其他forms的关系,但非常适合您的问题。