ActiveRecord::Migration 的 create_join_table 的行为是什么?
What is the behaviour of create_join_table of ActiveRecord::Migration?
我发现了一种在我的 Rails 应用程序中为我的 HABTM 关系生成连接 table 的好方法。
rails g migration CreateJoinTable table1 table2
这会生成一个 ActiveRecord::Migration
,它使用 create_join_table
方法
我想知道这个神奇的神秘方法有什么作用。我猜它会生成一个 table(可能没有 id
字段),其中有一列用于 table1 外键,一列用于 table2 外键,但是table 还有其他功能吗?。我对 join tables 的习惯一直是在这两个列之间添加一个唯一索引,这样 table1 中的记录和 table2 中的记录之间的关系就不会被输入两次.
我的问题归结为:如果我使用 create_join_table
,我是否需要继续添加该唯一索引,或者这种方法是否为我做(我认为应该)?
documentation I usually look at 没有涉及这种细节。
事实证明,它除了我在问题中描述的基础知识外,并没有做更多的事情。我只是通过 运行 迁移并查看 db/schema.rb
中的结果发现了这一点
对于那些感兴趣的人,要获得唯一索引,请执行以下操作:
class CreateJoinTable < ActiveRecord::Migration
def change
create_join_table :posts, :users
add_index :posts_users, [:post_id, :user_id], unique: true, name: 'index_posts_users'
end
end
在没有任何块的情况下调用,create_join_table
只是创建一个 table,其中有两个外键引用两个连接的 tables。
但是,当您调用该方法执行任何其他操作(例如,添加索引)时,您实际上可以传递一个块。来自 Rails 文档:
create_join_table :products, :categories do |t|
t.index :product_id
t.index :category_id
end
看看create_join_table
documentation。
您可以查看底部的create_join_table
代码(点击来源:显示)。
SchemaStatements#create_join_table() 只创建连接 table 没有任何花哨的索引等,...所以如果你想在两个字段上使用唯一性约束你必须做这样的事情:
class CreateJoinTable < ActiveRecord::Migration
def change
create_join_table :posts, :users do |t|
t.integer :post_id, index: true
t.integer :user_id, index: true
t.index [:post_id, :user_id], name: 'post_user_un', unique: true
end
end
end
Please also note that create_join_table
by default does NOT create id
field.
还要注意如何为此连接定义依赖销毁 table。
如果您稍后离开 HABTM 并使用 through:
定义关系并且弄错了,您可能 运行 进入我报告的 'to_sym' 错误 here。
确保你已经像这样定义了销毁:
class Proposal < ActiveRecord::Base
has_many :assignments
has_many :products, through: :assignments, dependent: :destroy # <- HERE
end
class Product < ActiveRecord::Base
has_many :assignments
has_many :proposals, through: :assignments, dependent: :destroy # <- HERE
end
class Assignment < ActiveRecord::Base
belongs_to :product
belongs_to :proposal
end
不是这个:
class Proposal < ActiveRecord::Base
has_many :assignments, dependent: :destroy
has_many :products, through: :assignments
end
class Product < ActiveRecord::Base
has_many :assignments, dependent: :destroy
has_many :proposals, through: :assignments
end
class Assignment < ActiveRecord::Base
belongs_to :product
belongs_to :proposal
end
我发现了一种在我的 Rails 应用程序中为我的 HABTM 关系生成连接 table 的好方法。
rails g migration CreateJoinTable table1 table2
这会生成一个 ActiveRecord::Migration
,它使用 create_join_table
我想知道这个神奇的神秘方法有什么作用。我猜它会生成一个 table(可能没有 id
字段),其中有一列用于 table1 外键,一列用于 table2 外键,但是table 还有其他功能吗?。我对 join tables 的习惯一直是在这两个列之间添加一个唯一索引,这样 table1 中的记录和 table2 中的记录之间的关系就不会被输入两次.
我的问题归结为:如果我使用 create_join_table
,我是否需要继续添加该唯一索引,或者这种方法是否为我做(我认为应该)?
documentation I usually look at 没有涉及这种细节。
事实证明,它除了我在问题中描述的基础知识外,并没有做更多的事情。我只是通过 运行 迁移并查看 db/schema.rb
对于那些感兴趣的人,要获得唯一索引,请执行以下操作:
class CreateJoinTable < ActiveRecord::Migration
def change
create_join_table :posts, :users
add_index :posts_users, [:post_id, :user_id], unique: true, name: 'index_posts_users'
end
end
在没有任何块的情况下调用,create_join_table
只是创建一个 table,其中有两个外键引用两个连接的 tables。
但是,当您调用该方法执行任何其他操作(例如,添加索引)时,您实际上可以传递一个块。来自 Rails 文档:
create_join_table :products, :categories do |t|
t.index :product_id
t.index :category_id
end
看看create_join_table
documentation。
您可以查看底部的create_join_table
代码(点击来源:显示)。
SchemaStatements#create_join_table() 只创建连接 table 没有任何花哨的索引等,...所以如果你想在两个字段上使用唯一性约束你必须做这样的事情:
class CreateJoinTable < ActiveRecord::Migration
def change
create_join_table :posts, :users do |t|
t.integer :post_id, index: true
t.integer :user_id, index: true
t.index [:post_id, :user_id], name: 'post_user_un', unique: true
end
end
end
Please also note that
create_join_table
by default does NOT createid
field.
还要注意如何为此连接定义依赖销毁 table。
如果您稍后离开 HABTM 并使用 through:
定义关系并且弄错了,您可能 运行 进入我报告的 'to_sym' 错误 here。
确保你已经像这样定义了销毁:
class Proposal < ActiveRecord::Base
has_many :assignments
has_many :products, through: :assignments, dependent: :destroy # <- HERE
end
class Product < ActiveRecord::Base
has_many :assignments
has_many :proposals, through: :assignments, dependent: :destroy # <- HERE
end
class Assignment < ActiveRecord::Base
belongs_to :product
belongs_to :proposal
end
不是这个:
class Proposal < ActiveRecord::Base
has_many :assignments, dependent: :destroy
has_many :products, through: :assignments
end
class Product < ActiveRecord::Base
has_many :assignments, dependent: :destroy
has_many :proposals, through: :assignments
end
class Assignment < ActiveRecord::Base
belongs_to :product
belongs_to :proposal
end