我正在使用rails 4.2,我只是想知道如果我在迁移中使用:foreign_key
关键字而不是仅添加user_id
列来添加与我的模型的关系会有什么不同?
答案 0 :(得分:4)
关键区别不是在应用程序层上,而是在数据库层上 - 外键用于使数据库强制执行参照完整性。
让我们看一个例子:
class User < ActiveRecord::Base
has_many :things
end
class Thing < ActiveRecord::Base
belongs_to :user
end
如果我们在没有外键的情况下声明things.user_id
:
class CreateThings < ActiveRecord::Migration
def change
create_table :things do |t|
t.integer :user_id
t.timestamps null: false
end
end
end
ActiveRecord很乐意允许我们在thing表上孤立行:
user = User.create(name: 'Max')
thing = user.things.create
user.destroy
thing.user.name # Boom! - 'undefined method :name for NilClass'
如果我们有一个外键,那么数据库就不会允许我们销毁user
,因为它会留下一个孤立的记录。
class CreateThings < ActiveRecord::Migration
def change
create_table :things do |t|
t.belongs_to :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
user = User.create(name: 'Max')
thing = user.things.create
user.destroy # DB says hell no
虽然您可以通过回调来简单地对此进行规范,但是强制执行引用完整性通常是一个好主意。
# using a callback to remove associated records first
class User < ActiveRecord::Base
has_many :things, dependent: :destroy
end