【问题标题】:Howto structure rails user friendships model?如何构建 Rails 用户友谊模型?
【发布时间】:2011-10-16 01:50:59
【问题描述】:

我需要创建一个用户Friendship (user1_id, user2_id) 模型来连接用户。

我希望避免为每个用户/朋友创建两条 Friendship 记录,因为友谊是双向的。

你会如何做到这一点,同时有点简单

# User.rb
has_many :friendships
has_many :friends, :through => :friendships, :class_name => "User"

编辑 我的解决方案是镜像记录:

class Friendship < ActiveRecord::Base
    belongs_to :user1
    belongs_to :user2

    after_create :create_mirror!
    after_destroy :destroy_mirror!

    validate :does_not_exist

    def mirror_record
      Friendship.where(:user1_id => user2.id, :user2_id => user1.id).first
    end

    private

    def does_not_exist
      errors.add(:base, 'already exists') if Friendship.where(:user1_id => user1.id, :user2_id => user2.id) rescue nil
    end

    def create_mirror!
      Friendship.create(:user1 => user2, :user2 => user1)
    end

    def destroy_mirror!
      mirror_record.destroy if mirror_record
    end
end

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3.1 rails-models


    【解决方案1】:

    也许这将使代码 sn-p 可以工作或为您提供一些灵感。它来自amistad gem。

    class User
      has_many :friendships
      has_many :invited, :through => :friendships, :source => :friend
      has_many :invited_by, :through => :inverse_friendships, :source => :user
    
      def friends
        self.invited + self.invited_by
      end
    
    class Friendships
      belongs_to :user
      belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
    

    因此,在您的控制器中,您可以编写 user.friends 之类的内容来获取所有朋友。

    【讨论】:

    • 我现在发布我想做的就是不镜像记录的噩梦,这是最好的也是唯一的解决方案。
    【解决方案2】:

    每个友谊只需要一个记录。 Friendship 类只有两个属性,每个属性都指向一个朋友。

    class Friendship
      belongs_to user1, :class_name => "User"
      belongs_to user2, :class_name => "User"
    

    ...你的桌子是...

    friendship_id | user1_id | user2_id
    -----------------------------------
    

    在 Rails 2.x 中,这被称为“拥有并属于多个”关系 (HABTM)。

    我相信您必须为每个 belongs_to 语句明确指定类名,因为它们都指向相同类型的父记录(User),因此您不能同时调用这两个字段user - 你必须以某种方式区分它们。

    【讨论】:

    • 这使得Friendship 模型工作,但User HABTM 关系仍然不起作用。您不能调用User.first.friends &lt;&lt; User.last 甚至User.first.friends,因为:source 只能有一个值,:game1:game2
    • 如果我错了,请纠正我,但has_many :friendshipshas_many :friends, :through =&gt; :friendships 不是多余的吗?也许我必须启动一个测试项目来看看会发生什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2012-04-05
    • 2011-12-01
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多