对add_reference, remove_reference, add_foreign_key, remove_foreign_key这四个有点拎不清,查了官方的API,记录下。
部分实例取自官网。
add_reference VS add_foreign_key
add_reference(table_name, ref_name, **options)
用来给表添加一个参考列,使用时,options可以有如下的设置:
:type 参考列的类型. 默认是 :bigint. :index 添加一个键. 默认是 true. :foreign_key 添加一个合适的外键约束. 默认是 false. :polymorphic 多态关联,也就是是否需要添加额外的_type. 默认是 false, 即不添加, 设置为true时,则添加上_type :null 该列是否允许为 nulls. 默认是 true.
以articles,authors为例,这里我们主要看添加外键:
add_reference :articles, :author, foreign_key: true
上面的这种用法,使用add_foreign_key可以这样写:
add_foreign_key :articles, :authors
默认添加的列名为author_id。
或者指定列名:
add_foreign_key :articles, :authors, column: :custom_author_id, primary_key: 'id'
add_foreign_key(from_table, to_table, options = {})
用来给表添加一个外键,使用时,options可以有如下的设置:
:column 外键列的名字. 默认是to_table的单数形式 + "_id" :primary_key to_table的主键. 默认是 id. :name 约束名或者说是外键的名称 默认是 fk_rails_<identifier> 样式,identifier是一个根据from_table和column来生成的总长为10的字符串,比如fk_rails_e74ce85cbc. :on_delete 发生删除时的行为,可设置为nullify,cascade, restrict :on_update 发生更新时的行为,同delete :validate 只用于Postgres, 指定是否应该验证约束. 默认是 true.
add_foreign_key还可以指定to_table主表delete或者update时,from_table从表的行为约束。
nullify:删除/更新主表时,自动更新从表值为NULL。删除/更新从表,主表不变
cascade:删除/更新主表时,自动删除/更新从表。删除/更新从表,主表不变
restrict:从表记录不存在时,主表才可以删除/更新。删除/更新从表,主表不变
两者的区别
add_foreign_key是用来添加外键的method,但是add_reference却不一定添加的就是外键,如果在options中,添加了
foreign_key: true
, 那么其效果就同add_foreign_key的基本用法。
remove_reference VS remove_foreign_key
remove_reference(table_name, ref_name, foreign_key: false, polymorphic: false, **options)
顾名思义,移除reference。
移除单个reference,同时移除index:
remove_reference(:products, :user, index: true)
移除设置为多态关联的reference:
remove_reference(:products, :supplier, polymorphic: true)
移除外键:
remove_reference(:products, :user, index: true, foreign_key: true)
remove_foreign_key(from_table, options_or_to_table = {})
移除外键约束。
移除一个外键, 这里移除了accounts的branch_id 这个外键:
remove_foreign_key :accounts, :branches
指定移除的外键列:
remove_foreign_key :accounts, column: :owner_id
指定移除的外键名称,这里移除了accounts表中名为special_fk_name的外键。「前面add_foreign_key中,可以通过name来设定添加的外键名称。」
remove_foreign_key :accounts, name: :special_fk_name
两者的区别
基本同添加外键一样,remove_reference当指定了
foreign_key: true
时,等同与remove_foreign_key。比如下面这个例子:remove_reference :groups, :order, foreign_key: true ## 等同于下面这两种写法 remove_foreign_key :groups, :orders remove_foreign_key :groups, column: :order_id