Rails migration
Generate migration
rails g migration MyVeryFristMigration # g = generate
rails will generate a file in format timestamp_my_very_first_migration.rb
class MyVeryFirstMigration < ActionRecord::Migration[5.0]
def change
# your migration code
end
end
rails is smart enough to understand to run up
or down
when run migration, for previous version, you can explicit write:
class MyVeryFristMigration < ActionRecord::Migration[5.0]
def up
# rails db:migrate or rake db:migration for prev version
end
def down
# rails db:rollback
end
end
Model generation
migration can be generated by generate a model as well:
rails g model User
then we got at least:
models/User.rb
db/timestamp_user.rb
To create a table, use the following code:
# 20190516100120_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
# t.column :column_name, :data_type, { options }
t.column :email, :string
t.string, :user_name # shorthand syntax
end
end
# rollback
# drop_table :users
end
data types:
- binary
- boolean
- date
- datetime
- decimal
- float
- integer # int
- string # nvarchar 225
- text # text
- time
options:
:limit # size
:default # default value
:null # true/false
# for decimal/float
:precision # number
:scale # number
For example:
def change
create_table :users do |t|
t.user_name, :string, limit: 50, null: false
t.email, :string, limit: 50
t.full_name, :string, default: "Anonymous" # limit: 225
t.debt, :decimal, precision: 10, scale: 2 # 12345678.91
end
end
If you want to use another column for identity, then you can turn off the default id:
def change
create_table users, id: false do |t|
# nah, you should not
end
end
Run migration
To run all pending migrations, run:
rails db:migrate # or rake db:migrate for prev version
To rollback latest migration, run:
rails db:rollback
or rollback to specific version:
rails db:rollback VERSION=timestamp
wait, what timestamp? say if you have 20190516100120_create_users.rb then timestamp is 20190516100120
#tips: to rollback to very first version:
rails db:rollback VERSION=0
VERSION has to be uppercased.
Other helpful migrate commands:
rails db:migration:status
rails db:migration:up VERSION=timestamp
rails db:migration:down VERSION=timestamp
rails db:migration:redo VERSION=timestamp
Migration (mi) methods
1. Table mi
# create table
create_table(table, options) do |t|
end
# Ex:
create_table :users do |t|
t.user_name, :string, limit: 50, null: false
end
# drop table
drop_table(table)
# rename table
rename_table(table, new_table_name)
2. Column mi
add_column(table, column, type, options)
# Ex:
add_column :users, :user_type, :integer, default: 0
remove_column(table, column)
rename_column(table, column, new_name)
change_column(table, column, type, option)
3. Index mi
add_index(table, column, options) # should add index for all FKs
# Ex:
add_index :users, :user_contacts
remove_index(table, column)
where index options are:
unique: true/false
name: "your_custom_index_name"
Fix migration errors
If you have issue when run migration, for example column already exist, you can use rails console to fix it:
ActiveRecord::Migration.remove_column :table_name, :column_name