"add_foreign_key"和"add_reference"方法在Rails中有什么区别?
根据Rails官方指南,我理解的是它们都用于在两个表之间创建外键约束。
"add_foreign_key"和"add_reference"方法在Rails中有什么区别?
根据Rails官方指南,我理解的是它们都用于在两个表之间创建外键约束。
add_foreign_key
- 添加一个新的外键。 from_table
是具有键列的表,to_table
包含参考主键。
add_reference
- 旨在为同时创建列、索引和外键提供快捷方式。
什么是外键
- 外键是表中的一个或一组字段,用于唯一标识另一张表中的行。
(注意:本答案基于Rails 6.0版本。)
简单来说,add_reference
(Ref) 是一种缩写形式,相当于同时使用 add_column
、add_index
和 add_foreign_key
(Ref),但默认不添加数据库级别的外键。因此,当你想要实现比较简单的功能或者(相反地?)多态引用时,add_reference
很方便。如果不是这种情况,可以使用 add_foreign_key
,也许需要结合明确的 add_index
使用。
举个简单的例子,我认为以下两者是等价的:
add_reference :articles, :author, foreign_key: true
add_column :articles, :author_id, :bigint, null: true
add_foreign_key :articles, :authors
add_index :articles, :author_id
以下是更详细的区别:
add_reference
的第二个参数是引用(没有 _id
的列名,通常是单数形式),而 add_foreign_key
的第二个参数是表名(通常是复数形式)。add_reference
中,
foreign_key
选项。index: true
是默认值,在 add_foreign_key
中索引是无关紧要的。null: true
是默认值(允许该列为空),在 add_foreign_key
中无关紧要。polymorphic: true
仅在 Rails 的 add_reference
中可用(它将在一个操作中创建两个列; 参见 Ref)。add_reference
可以接受更广泛的选项范围,但两者接受选项的格式完全不同。对于禁止为空的 has_one
关联:
add_reference :products, :merchant, null: false, index: {unique: true}, foreign_key: {on_delete: :cascade}
当一个表有两个外键列指向相同的表时:
add_foreign_key :products, :merchants, column: :seller_id
add_foreign_key :products, :merchants, column: :buyer_id
add_index :products, [:seller_id, :buyer_id], unique: true, name: 'index_my_name_shorter_than_64chars'
相比于add_foreign_key,add_reference有一定的限制。
我很好奇是否有一种方法可以使用add_reference来实现完全相同的操作。据我所知,标准的外键到主键/参考键映射不能通过add_reference进行分歧。
迁移片段
add_foreign_key :foos, :bars, column: :foo_key, primary_key: :foo_key, type: :string
add_index :foos
使用情况是当尝试以非标准方式将外键映射到主键时。例如,使用一张包含STI的表来保存多个引用
add_reference
的foreign_key
选项默认为false,传递true以添加。 https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_reference - pixelearth