在 rails 中与 has_and_belongs_to_many 建立友谊模型
Implement a friendship model with has_and_belongs_to_many in rails
我有用户模型,我在 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
我需要获取特定用户的所有好友,我该怎么做?
实现两个用户之间的友谊
我假设您愿意实施像 Facebook 这样的友谊模式:
- 用户请求与另一个用户建立友谊
- other other 必须接受好友请求
- 只有经过这两步用户才是真正的朋友
为此,我们需要一个友谊模型来代替您的 has_many_and_belongs_to
-内置函数。友谊模型将帮助我们识别用户之间活跃的和未决的友谊请求。友情模型只有一个用户(发起者)和一个好友(用户发送请求的人)。
场景:
- 你向Joe发送请求->友谊模型创建,你是'user',joe是'friend'
- Joe 接受您的友谊 -> 已创建友谊模型,Joe 是 'user',您是 'friend'
- 使用 2 个辅助函数
active_friends
和 pending_friends
您可以获得视图数据或 API
# 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-like
# user.rb
has_many :friendships, dependent: :destroy
has_many :friends, through: :friendships
获取其他人发送给 "you"
的好友
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
我有用户模型,我在 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
我需要获取特定用户的所有好友,我该怎么做?
实现两个用户之间的友谊
我假设您愿意实施像 Facebook 这样的友谊模式:
- 用户请求与另一个用户建立友谊
- other other 必须接受好友请求
- 只有经过这两步用户才是真正的朋友
为此,我们需要一个友谊模型来代替您的 has_many_and_belongs_to
-内置函数。友谊模型将帮助我们识别用户之间活跃的和未决的友谊请求。友情模型只有一个用户(发起者)和一个好友(用户发送请求的人)。
场景:
- 你向Joe发送请求->友谊模型创建,你是'user',joe是'friend'
- Joe 接受您的友谊 -> 已创建友谊模型,Joe 是 'user',您是 'friend'
- 使用 2 个辅助函数
active_friends
和pending_friends
您可以获得视图数据或 API
# 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-like
# user.rb
has_many :friendships, dependent: :destroy
has_many :friends, through: :friendships
获取其他人发送给 "you"
的好友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