在rails中使用has_and_belongs_to_many实现友谊模型

时间:2018-03-10 21:00:00

标签: ruby-on-rails has-and-belongs-to-many

我有用户模型,我在Rails上使用has_and_belongs_to_many来建立用户和朋友模型之间的关系。
用户可以有很多朋友,朋友可以有很多朋友。我需要得到特定用户的所有朋友,我该怎么做?

user.rb 文件中:

has_and_belongs_to_many :friendships, class_name: "User", join_table:  :friendships,
                          foreign_key: :user_id,
                          association_foreign_key: :friend_user_id}

20180309142447_create_friendships_table.rb 档案:

class CreateFriendshipsTable < ActiveRecord::Migration[5.1]
  def change
    create_table :friendships, id: false do |t|
      t.integer :user_id
      t.integer :friend_user_id
    end

    add_index(:friendships, [:user_id, :friend_user_id], :unique => true)
    add_index(:friendships, [:friend_user_id, :user_id], :unique => true)
  end
end

我需要获得特定用户的所有朋友,我该怎么做?

1 个答案:

答案 0 :(得分:1)

在两个用户之间实现友谊

我认为你愿意像Facebook一样实施友谊模式:

  1. 用户请求其他用户的友情
  2. 其他其他人必须接受友谊请求
  3. 只有在这两个步骤后,用户才是真正的朋友
  4. 为此我们需要一个友谊模型来取代你的has_many_and_belongs_to - 内置函数。友谊模型将帮助我们识别用户之间的活动和待处理的友谊请求。友谊模型只有一个用户(发起者)和一个朋友(用户发送请求)。

    情景:

    1. 您向Joe发送请求 - &gt;友情模型创建,你是'用户',乔是'朋友'
    2. 乔接受你的友谊 - &gt;友情模型创建,乔是'用户',你是'朋友'
    3. 使用2个辅助函数active_friendspending_friends,您可以获取视图或API的数据
    4. # new migration
      # $ rails g migration create_friendships
      def change
        create_table :friendships do |t|
          t.integer :user_id
          t.integer :friend_id
          t.timestamps null: false
        end
      end
      

      创建一个新的友谊模型

      # friendship.rb
      class Friendship < ActiveRecord::Base
      
        # - RELATIONS
        belongs_to :user
        belongs_to :friend, class_name: 'User'
      
        # - VALIDATIONS
        validates_presence_of :user_id, :friend_id
        validate :user_is_not_equal_friend
        validates_uniqueness_of :user_id, scope: [:friend_id]
      
        def is_mutual
          self.friend.friends.include?(self.user)
        end
      
        private
        def user_is_not_equal_friend
          errors.add(:friend, "can't be the same as the user") if self.user == self.friend
        end
      
      end
      

      在您的用户模型中,您可以处理类似rails的友情

      # user.rb
      has_many :friendships, dependent: :destroy
      has_many :friends, through: :friendships
      

      将某人的友情发送给“你”

      has_many :received_friendships, class_name: 'Friendship', foreign_key: 'friend_id'
      has_many :received_friends, through: :received_friendships, source: 'user'
      
      def active_friends
        friends.select{ |friend| friend.friends.include?(self) }  
      end
      
      def pending_friends
        friends.select{ |friend| !friend.friends.include?(self) }  
      end