是否可以在我的迁移中使用:foreign_key而不仅仅是添加user_id?

时间:2016-05-14 12:46:48

标签: ruby-on-rails ruby ruby-on-rails-4

我正在使用rails 4.2,我只是想知道如果我在迁移中使用:foreign_key关键字而不是仅添加user_id列来添加与我的模型的关系会有什么不同?

1 个答案:

答案 0 :(得分:4)

YES

关键区别不是在应用程序层上,而是在数据库层上 - 外键用于使数据库强制执行参照完整性。

让我们看一个例子:

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