Skip to content

Instantly share code, notes, and snippets.

@Atlas7
Last active March 1, 2016 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Atlas7/ef1b3cf373fc07aba5c7 to your computer and use it in GitHub Desktop.
Save Atlas7/ef1b3cf373fc07aba5c7 to your computer and use it in GitHub Desktop.
Rails - Model Association and Migration

Say we have two models like this:

class Supplier < ActiveRecord::Base
  has_one :account
end

class Account < ActiveRecord::Base
  belongs_to :supplier
end

For suppliers the migration file is simple:

class CreateSuppliers < ActiveRecord::Migration
  def change
    create_table :suppliers do |t|
      t.string :name
      t.timestamps null: false
    end
  end
end

Just learnt today that the following migrations files for accounts are all equivalent:

add_index style:

class CreateAccounts < ActiveRecord::Migration
  def change
    create_table :accounts do |t|
      t.integer :supplier_id
      t.string :account_number
      t.timestamps null: false
    end
    add_index :accounts, :supplier_id
  end
end

add_reference style:

class CreateAccounts < ActiveRecord::Migration
  def change
    create_table :accounts do |t|
      t.string :account_number
      t.timestamps null: false
    end
    add_references :accounts, :supplier, index:true
  end
end

t.belongs_to style

class CreateAccounts < ActiveRecord::Migration
  def change
    create_table :accounts do |t|
      t.belongs_to :supplier, index: true
      t.string :account_number
      t.timestamps null: false
    end
  end
end

t.references style

class CreateAccounts < ActiveRecord::Migration
  def change
    create_table :accounts do |t|
      t.references :supplier, index: true
      t.string :account_number
      t.timestamps null: false
    end
  end
end

# Schema

The schema will look like this:

ActiveRecord::Schema.define(version: 20160301092619) do

  create_table "accounts", force: :cascade do |t|
    t.integer  "supplier_id"
    t.string   "account_number"
    t.datetime "created_at",     null: false
    t.datetime "updated_at",     null: false
  end

  add_index "accounts", ["supplier_id"], name: "index_accounts_on_supplier_id"

  create_table "suppliers", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end

# On Foreign Keys

Next to the above index: true option, we may also add a , foreign_key: true to keep the referential integrity.

ie. if a supplier is deleted / destroyed, the corresonding account is also deleted / destroyed. We no longer need to specify the dependent: destroy.

(See this article for more info on referential integrity)[https://robots.thoughtbot.com/referential-integrity-with-foreign-keys]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment