【发布时间】:2016-05-14 12:46:47
【问题描述】:
我正在使用 rails 4.2,我只想知道如果我在迁移中使用 :foreign_key 关键字而不是仅仅添加 user_id 列来添加与我的模型的关系是否会有任何区别?
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-4
我正在使用 rails 4.2,我只想知道如果我在迁移中使用 :foreign_key 关键字而不是仅仅添加 user_id 列来添加与我的模型的关系是否会有任何区别?
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-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 将很高兴地允许我们在 things 表上孤立行:
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
【讨论】:
belongs_to 宏,无论如何都可以完成声明列时guides.rubyonrails.org/…