Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
become active record migration expert (Rails 4.0.2)

become active record migration expert (Rails 4.0.2)


create model

$ rails g model NameOfModel
    invoke  active_record
    create    db/migrate/YYYYMMDDHHMMSS_create_name_of_models.rb
    create    app/models/name_of_model.rb
    invoke    test_unit
    create      test/models/name_of_model_test.rb
    create      test/fixtures/name_of_models.yml

create name_of_models table and define some columns

  1. open db/migrate/YYYYMMDDHHMMSS_create_name_of_models.rb

  2. define field in format t.field_type :field_name

class CreateNameOfModels < ActiveRecord::Migration
    def change
        create_table :name_of_models do |t|
            t.string :name
            t.integer :age
  1. run rake db:migrate
$ rake db:migrate
==  CreateNameOfModels: migrating =============================================
-- create_table(:name_of_models)
   -> 0.0085s
==  CreateNameOfModels: migrated (0.0087s) ====================================

this will create name_of_models table with name and age columns.

updating name_of_models table

add another column

  1. run rails generator with Add[column]To[model] format followed by column
$ rails g migration AddBioToNameOfModels bio:text
    invoke  active_record
    create    db/migrate/YYYYMMDDHHMMSS_add_bio_to_name_of_models.rb
  1. open db/migrate/YYYYMMDDHHMMSS_add_bio_to_name_of_columns.rb
class AddBioToNameOfModels < ActiveRecord::Migration
  def change
    add_column :name_of_models, :bio, :text
  1. run rake db:migrate
› rake db:migrate
==  AddBioToNameOfModels: migrating ===========================================
-- add_column(:name_of_models, :bio, :text)
   -> 0.0067s
==  AddBioToNameOfModels: migrated (0.0069s) ==================================

add multiple columns at once

  1. run rails generator with AddDetailsTo[model] format followed by list of columns
$ rails g migration AddDetailsToNameOfModels first_name last_name phone_number anothertables:belongs_to
    invoke  active_record
    create    db/migrate/YYYYMMDDHHMMSS_add_details_to_name_of_models.rb
  1. open up db/migrate/YYYYMMDDHHMMSS_add_details_to_name_of_models.rb
class AddDetailsToNameOfModels < ActiveRecord::Migration
    def change
        add_column :name_of_models, :first_name, :string
        add_column :name_of_models, :last_name, :string
        add_column :name_of_models, :phone_number, :string
        add_reference :name_of_models, :anothertables, index: true

make sure you have exactly column name and type before migrating

  1. run rake db:migrate
$ rake db:migrate
==  AddDetailsToNameOfModels: migrating =======================================
-- add_column(:name_of_models, :first_name, :string)
   -> 0.0068s
-- add_column(:name_of_models, :last_name, :string)
   -> 0.0009s
-- add_column(:name_of_models, :phone_number, :string)
   -> 0.0008s
-- add_reference(:name_of_models, :anothertables, {:index=>true})
   -> 0.0016s
==  AddDetailsToNameOfModels: migrated (0.0108s) ==============================

remove column

  1. run rails generator with Remove[column]From[model] format followed by column you want to remove
$ rails g migration RemovePhoneNumberFromNameOfModels phone_number:string
      invoke  active_record
      create    db/migrate/YYYYMMDDHHMMSS_remove_phone_number_from_name_of_models.rb
  1. open db/migrate/YYYYMMDDHHMMSS_remove_phone_number_from_name_of_models to make sure.
class RemovePhoneNumberFromNameOfModels < ActiveRecord::Migration
    def change
        remove_column :name_of_models, :phone_number, :string

remove multiple columns at once

  1. run rails generator with RemoveDetailsFrom[model] format followed by column you want to remove
› rails g migration RemoveDetailsFromNameOfModels first_name last_name anothertables:belongs_to
      invoke  active_record
      create    db/migrate/YYYYMMDDHHMMSS_remove_details_from_name_of_models.rb
  1. open db/migrate/YYYYMMDDHHMMSS_remove_details_from_name_of_models.rb
class RemoveDetailsFromNameOfModels < ActiveRecord::Migration
    def change
        remove_column :name_of_models, :first_name, :string
        remove_column :name_of_models, :last_name, :string
        remove_reference :name_of_models, :anothertables, index: true
  1. if you are sure with what you do, then run rake db:migrate. it will remove all column or reference that you define on db/migrate/YYYYMMDDHHMMSS_remove_details_from_name_of_models.rb


  • when you migrate the wrong table you can rollback using rake db:rollback
  • update your table with create new migration (add/remove).

I think, updating your table by editing your previous migration is not best practice. my experience updating table by editing my previous migration and then execute rake db:migrate is doesn't work.

more resource

Active Record Migrations

AnjanJ commented Sep 30, 2015

Great explanation. made everything so simple.
Thanks for the post

harsh183 commented Dec 1, 2015

Thanks for this post, it makes things very clear.

is it possible to create new generator that drop_table / change column name or type / remove columns / change table name.

For example I would like to be able to write:
Rails g migration DropTable User

and without any file migration edition run:
rake db:migrate

AdKnob commented Apr 8, 2017

Thank you. Finally clicked for me.

Iqlaas commented Jun 19, 2017

If you could add that you could verify the migration works in the console it would be perfect !

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