StormTrooper StormTrooper - 6 months ago 10
Ruby Question

Is it advisable to use :foreign_key in my migrations rather than just adding user_id?

I am using rails 4.2, I just want to know if there would be any difference if I use the

:foreign_key
keyword in my migrations rather than just adding a
user_id
column to add relationship to my models ?

max max
Answer

YES

The key difference is not on the application layer but on the database layer - foreign keys are used to make the database enforce referential integrity.

Lets look at an example:

class User < ActiveRecord::Base
  has_many :things
end

class Thing < ActiveRecord::Base
  belongs_to :user
end

If we declare things.user_id without a foreign key:

class CreateThings < ActiveRecord::Migration
  def change
    create_table :things do |t|
      t.integer :user_id

      t.timestamps null: false
    end
  end
end

ActiveRecord will happily allow us to orphan rows on the things table:

user = User.create(name: 'Max')
thing = user.things.create
user.destroy
thing.user.name # Boom! - 'undefined method :name for NilClass'

While if we had a foreign key the database would not allow us to destroy user since it leaves an orphaned record.

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

While you can simply regulate this with callbacks having the DB enforce referential integrity is usually a good idea.

# using a callback to remove associated records first
class User < ActiveRecord::Base
  has_many :things, dependent: :destroy
end
Comments