gpt4 book ai didi

ruby-on-rails - 在 Rails 中实现友谊模型的最佳方式

转载 作者:行者123 更新时间:2023-12-01 01:05:19 24 4
gpt4 key购买 nike

我想在我的应用程序中实现一个用户的 friend 系统,所以我发现 rails space 解决方案非常好,想法是创建 两行the Friendships table : 第一行是发送者邀请,第二行是接收者
使用 has_many 设置用户之间的关系协会是这样的:

has_many :friendships
has_many :friends, :through => :friendships, :conditions => "status = 'accepted'"
接受用户为 friend 的方法是这样的:
# Accept a friend request.
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
accept_one_side() 方法是:
# Update the db with one side of an accepted friendship request.
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
这样做的好处是我们可以执行一个请求来获取双方的所有 friend (无论是用户发送邀请还是 friend 发送邀请)
但我认为这有缺点,例如,如果现实中有 500 个 friend ,Friendships 表将包含“500X2 = 1000”行
第二种解决方案是与 has_many through做反向关联如 RailsCast #163 Self-Referential Association 中所述:
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user
但在这里,如果你想为一个用户获取所有 friend ,你应该使用两个请求:
user.friends
user.inverse_friends
如果您有一个巨大的 Friendships 表,这根本不是最好的方法......
我想知道的是上面两种方法中最好的一种方法是什么,然后有一种方法可以优化它?如果还有另一种 super 方法,我将不胜感激

最佳答案

我更喜欢 friend 之间需要两个连接的版本,每个方向一个。原因与您提到的相同:它允许对用户的 friend 进行更多类似 Rails 的查询。

此外,我认为为友谊请求(一个方向)和现有友谊(两个方向)设置不同的表格会更清楚

由于您在中间有一个友谊模型,我建议使用回调的魔力。如果你定义了一些回调,那么你肯定只需要为连接的一侧分一杯羹,回调应该能够创建(或删除)匹配的补码。

# in friendship_requests
after_save :created_friendship

def accept
update_attributes(:status => 'accepted')
end

private
def created_friendship
sender.friends << receiver if status_changed? && status == 'accepted'
end


# in user.rb
has_and_belongs_to_many :friends, after_add: :create_complement_friendship,
after_remove: :remove_complement_friendship

private
def create_complement_friendship(friend)
friend.friends << self unless friend.friends.include?(self)
end

def remove_complement_friendship(friend)
friend.friends.delete(self)
end

这只是第一个想法,当然缺少一些验证器和回调......

关于ruby-on-rails - 在 Rails 中实现友谊模型的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19339596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com