class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps null: false #modifier
end
end
end
class CreateProducts < ActiveRecord::Migration
def up
create_table :products do |t|
t.string :name
t.text :description
t.timestamps null: false #modifier
end
end
def down
drop_table :products
end
end
1_create_products.rb ****************
* Products *
****************
* id *
* name *
* description *
****************
2_create_customers.rb **************** ****************
* Products * * Customers *
**************** ****************
* id * * id *
* name * * name *
* description * * email *
**************** ****************
3_add_phone_to_customer.rb **************** ****************
* Products * * Customers *
**************** ****************
* id * * id *
* name * * name *
* description * * email *
**************** * phone *
****************
$ bin/rails generate migration AddPhoneToCustomers
will create
class AddPhoneToCustomers < ActiveRecord::Migration
def change
end
end
$ bin/rails generate migration AddPhoneToCustomers phone:string
will create
class AddPhoneToCustomers < ActiveRecord::Migration
def change
add_column :customers, :phone, :string
end
end
$ bin/rails generate model Product name:string description:text
will create
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps null: false
end
end
end
In addition to the model itself
create_table :products do |t|
t.string :name
end
will implicitly create a primary key called id. Name can be changed using :primary_key option. If you dont want a primary key, pass option id: false
create_join_table :products, :categories
Creates a HABTM(has and belongs to many) join table.
***********************
* categories_products *
***********************
* category_id *
* product_id *
***********************
change_table :products do |t|
t.remove :description, :name
t.string :part_number
t.index :part_number
t.rename :upccode, :upc_code
end
change_column :products, :part_number, :text
note: change_column is irreversible
Can be applied when creating or changing columns
add_foreign_key :articles, :authors
Adds a foreign key to the author_id column of the articles table.
Available options: :column :primary_key :name
# let Active Record figure out the column name
remove_foreign_key :articles, :authors
# remove foreign key for a specific column
remove_foreign_key :articles, column: :author_id
# remove foreign key by name
remove_foreign_key :articles, name: :special_fk_name
Product.connection.execute("UPDATE products SET price = 'free' WHERE 1=1")
Primary way of writing migrations. Active Record knows how to reverse.
Supported definitions:
add_column add_foreign_key add_index
add_reference add_timestamps change_column_default (must supply a :from and :to option)
change_column_null create_join_table create_table
disable_extension drop_join_table drop_table (must supply a block)
enable_extension remove_index remove_column (must supply a type)
remove_reference remove_timestamps remove_foreign_key (must supply a second table)
rename_column rename_index rename_table
when Active Record doesn't know how to reverse
class ExampleMigration < ActiveRecord::Migration
def change
create_table :distributors do |t|
t.string :zipcode
end
reversible do |dir|
dir.up do
# add a CHECK constraint
execute <<-SQL
ALTER TABLE distributors
ADD CONSTRAINT zipchk
CHECK (char_length(zipcode) = 5) NO INHERIT;
SQL
end
dir.down do
execute <<-SQL
ALTER TABLE distributors
DROP CONSTRAINT zipchk
SQL
end
end
add_column :users, :home_page_url, :string
rename_column :users, :email, :email_address
end
end
"Old style"
class ExampleMigration < ActiveRecord::Migration
def up
create_table :distributors do |t|
t.string :zipcode
end
# add a CHECK constraint
execute <<-SQL
ALTER TABLE distributors
ADD CONSTRAINT zipchk
CHECK (char_length(zipcode) = 5);
SQL
add_column :users, :home_page_url, :string
rename_column :users, :email, :email_address
end
def down
rename_column :users, :email_address, :email
remove_column :users, :home_page_url
execute <<-SQL
ALTER TABLE distributors
DROP CONSTRAINT zipchk
SQL
drop_table :distributors
end
end
$ bin/rake db:migrate
Will run all migrations that have not yet been run.
$ bin/rake db:migrate VERSION=20150906120000
Will run up or down to specific version. Will not run down on this version if moving down.
$ bin/rake db:rollback
Revert last migration
$ bin/rake db:rollback STEP=3
Revert last 3 migrations
$ bin/rake db:setup
Create the database, load the schema.
$ bin/rake db:reset
Drop the database and set it up again. Equivalent to rake db:drop db:setup
Must rollback, edit, then rake db:migrate.
Should not edit migrations that are committed to source control. Create a new migration that performs the changes you require.
Migrations are not the authoritative source for your database schema.
db/schema.rb or an SQL file has that role. They should not be edited.
I deploying a new instance of an application. No need to run all migrations, just load the schema. db:setup (db:schema:load)
The schema can be dumped as SQL or ruby depending on setting config.active_record.schema_format in config/application.rb
# db/schema.rb
ActiveRecord::Schema.define(version: 20150906171750) do
create_table "authors", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "products", force: true do |t|
t.string "name"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
t.string "part_number"
end
end
The ruby version will be database-independent and can be loaded in any database that Active Record support. But this cannot express database specific items (triggers, stored procedures or check constraints). If using features like this, use the SQL version.
When using SQL. The schema dump will be database-specific and stored in db/structure.sql