【问题标题】:Is it advisable to use :foreign_key in my migrations rather than just adding user_id?是否建议在我的迁移中使用 :foreign_key 而不仅仅是添加 user_id?
【发布时间】:2016-05-14 12:46:47
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

是的

关键区别不在于应用层,而在于数据库层——外键用于使数据库强制引用完整性。

让我们看一个例子:

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

【讨论】:

  • 确保你索引外键列——你可能无论如何都会这样做,但是在数据库中声明了一个外键,确保你这样做是明智的。有一个宝石可以帮助解决这个问题......不记得名字......
  • 我想你可能会想到 foreigner 但是你不需要 gem 来在以后的迁移中添加外键或索引 - 如果你使用 belongs_to 宏,无论如何都可以完成声明列时guides.rubyonrails.org/…
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 2015-02-09
  • 1970-01-01
相关资源
最近更新 更多