我希望在追求这种关联之前确保我的方法是正确的。实施听起来太复杂了,所以我认为我的计划肯定有问题。我正在使用结构化(SQL)数据存储,符合rails存储约定。我所拥有的是用户模型,它在模式中有一个电子邮件地址password_digest
和名称。
class User < ActiveRecord::Base
has_many :posts
end
我想与朋友集合实现has_many
关联,以便用户可以belong_to
用户(作为朋友)。我希望能够在正确构建和填充后User.last.friends.last
返回User对象。
我相信我可以为这种协会创建一个模型,如:
Class Friend < ActiveRecord::Base
belongs_to :user
belongs_to :friendlies, class: 'User'
end
Class User < ActiveRecord::Base
has_many :posts
has_many :friends
has_many :friendly, class: 'Friend'
end
但我认为这需要我使用User.last.friends.last.user
添加关于模型和查询的内容所以我在想的是这是一个has_and_belongs_to_many
关系。我可以逃避以下(或类似的事情):
class User < ActiveRecord::Base
has_and_belongs_to_many :friends, class: 'User'
end
我找到this:
class User < ActiveRecord::Base
has_many :user_friendships
has_many :friends, through: :user_friendships
class UserFriendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, class_name: 'User', foreign_key: 'friend_id'
this(自称'标准'):
has_many :friendships, :dependent => :destroy
has_many :friends, :through => :friendships, :dependent => :destroy
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id", :dependent => :destroy
has_many :inverse_friends, :through => :inverse_friendships, :source => :user, :dependent => :destroy
我假设需要Friendship
模型。我觉得我不需要友谊模特。我认为class UserFriendship
方法看起来正确,但它需要一个额外的模型。现在回答问题:
我可以与将用户与用户朋友关联的表格建立has_and_belongs_to_many
关系,而不会产生额外的模型吗?
谨慎使用额外的模型“以防万一”以后会出现额外的要求吗?
答案 0 :(得分:7)
您正在寻找的是self referential join
,这意味着您可以使用不同的关联引用相同的model
:
#app/models/user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :friendships,
class_name: "User",
join_table: :friendships,
foreign_key: :user_id,
association_foreign_key: :friend_user_id
end
您必须创建一个habtm
联接表以获得参考:
$ rails g migration CreateFriendshipsTable
#db/migrate/create_friendships_table____.rb
class CreateFriendShipsTable < ActiveRecord::Migration
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
$ rake db:migrate
这里有一个很好的参考:Rails: self join scheme with has_and_belongs_to_many?
是否谨慎使用其他型号以防“以后会出现其他要求?”
只有当你知道时才会有额外的属性。如果没有,您可以根据需要随时使用habtm
。
答案 1 :(得分:5)
你可以试试这个
- friendship.rb
class Friendship < ApplicationRecord
belongs_to :user
belongs_to :friend, :class_name => 'User'
end
- user.rb
class User < ApplicationRecord
has_many :friendships
has_many :friends, through: :friendships
end
- db migrate xxxx_create_friendship.rb
class CreateFriendships < ActiveRecord::Migration[5.0]
def change
create_table :friendships do |t|
t.belongs_to :user
t.belongs_to :friend, class: 'User'
t.timestamps
end
end
end
答案 2 :(得分:1)
# app/model/user.rb
has_and_belongs_to_many :friends,
class_name: "User",
join_table: :friends_users,
foreign_key: :user_id,
association_foreign_key: :friend_id
此迁移已足够(不修改生成的代码):
rails g migration CreateFriendlyJoinTable users friends
使用rails generate migration -h