I would like to create a structure of Users
having many friends
, also of class User
:
我想创建一个拥有很多朋友的用户结构,也是类User:
class User < ActiveRecord::Base
has_and_belongs_to_many :friends, class_name: "User"
end
I do not need any details of their relationship thus I do not use :through
with kind of class Friendship
. But now I cannot find any way how to create corresponding database (neither with migration file nor using rails g model User username:string ...
command). Any ideas?
我不需要他们关系的任何细节因此我不使用:通过类友谊。但是现在我找不到任何方法来创建相应的数据库(既不使用迁移文件也不使用rails g model User username:string ...命令)。有任何想法吗?
1 个解决方案
#1
31
Here are some resources which may be helpful:
以下是一些可能有用的资源:
- RailsCasts episode #163 Self-Referential Association regarding self-referential many-to-many relationships
- RailsCasts第163集关于自我指涉多对多关系的自我指涉协会
- RailsCasts episode #47 Two Many-to-Many. This might be more relevant to what you're attempting to accomplish
- RailsCasts第47集两个多对多。这可能与您尝试完成的内容更为相关
- A gist someone created for self-referential relationships using HABTM
- 使用HABTM为自我指涉关系创建的要点
I'll summarize the information found in those links:
我将总结这些链接中的信息:
Given that you're describing a self-referential many-to-many relationship, you will of course end up with a join table. Normally, the join table should be deliberately named in such a way that Rails will automatically figure out which models the table is joining, however the "self-referential" part makes this a tad awkward, but not difficult. You'll merely have to specify the name of the join table, as well as the joining columns.
鉴于您正在描述自引用的多对多关系,您当然最终会得到一个连接表。通常情况下,连接表应该以这样的方式故意命名,即Rails会自动确定表加入的模型,但是“自引用”部分使这有点尴尬,但并不困难。您只需指定连接表的名称以及连接列。
You'll need to create this table using a migration that will probably look something like this:
您需要使用可能如下所示的迁移创建此表:
class CreateFriendships < ActiveRecord::Migration
def self.up
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
def self.down
remove_index(:friendships, [:friend_user_id, :user_id])
remove_index(:friendships, [:user_id, :friend_user_id])
drop_table :friendships
end
end
I'm not certain whether there is a shortcut way of creating this table, but bare minimum you can simply do rails g migration create_friendships
, and fill in the self.up
and self.down
methods.
我不确定是否有创建此表的快捷方式,但最低限度你可以简单地执行rails g migration create_friendships,并填写self.up和self.down方法。
And then finally in your user model, you simply add the name of the join table, like so:
最后在您的用户模型中,您只需添加连接表的名称,如下所示:
class User < ActiveRecord::Base
has_and_belongs_to_many :friends,
class_name: "User",
join_table: :friendships,
foreign_key: :user_id,
association_foreign_key: :friend_user_id
end
As you can see, while you do have a join table in the database, there is no related join model.
如您所见,虽然数据库中有连接表,但没有相关的连接模型。
Please let me know whether this works for you.
请告诉我这是否适合您。
#1
31
Here are some resources which may be helpful:
以下是一些可能有用的资源:
- RailsCasts episode #163 Self-Referential Association regarding self-referential many-to-many relationships
- RailsCasts第163集关于自我指涉多对多关系的自我指涉协会
- RailsCasts episode #47 Two Many-to-Many. This might be more relevant to what you're attempting to accomplish
- RailsCasts第47集两个多对多。这可能与您尝试完成的内容更为相关
- A gist someone created for self-referential relationships using HABTM
- 使用HABTM为自我指涉关系创建的要点
I'll summarize the information found in those links:
我将总结这些链接中的信息:
Given that you're describing a self-referential many-to-many relationship, you will of course end up with a join table. Normally, the join table should be deliberately named in such a way that Rails will automatically figure out which models the table is joining, however the "self-referential" part makes this a tad awkward, but not difficult. You'll merely have to specify the name of the join table, as well as the joining columns.
鉴于您正在描述自引用的多对多关系,您当然最终会得到一个连接表。通常情况下,连接表应该以这样的方式故意命名,即Rails会自动确定表加入的模型,但是“自引用”部分使这有点尴尬,但并不困难。您只需指定连接表的名称以及连接列。
You'll need to create this table using a migration that will probably look something like this:
您需要使用可能如下所示的迁移创建此表:
class CreateFriendships < ActiveRecord::Migration
def self.up
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
def self.down
remove_index(:friendships, [:friend_user_id, :user_id])
remove_index(:friendships, [:user_id, :friend_user_id])
drop_table :friendships
end
end
I'm not certain whether there is a shortcut way of creating this table, but bare minimum you can simply do rails g migration create_friendships
, and fill in the self.up
and self.down
methods.
我不确定是否有创建此表的快捷方式,但最低限度你可以简单地执行rails g migration create_friendships,并填写self.up和self.down方法。
And then finally in your user model, you simply add the name of the join table, like so:
最后在您的用户模型中,您只需添加连接表的名称,如下所示:
class User < ActiveRecord::Base
has_and_belongs_to_many :friends,
class_name: "User",
join_table: :friendships,
foreign_key: :user_id,
association_foreign_key: :friend_user_id
end
As you can see, while you do have a join table in the database, there is no related join model.
如您所见,虽然数据库中有连接表,但没有相关的连接模型。
Please let me know whether this works for you.
请告诉我这是否适合您。