1.) Create a new table
rails g migration CreateTask title:string description:text
class AddStartDateToTask < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :title
t.text :description
t.timestamps
end
end
end
2.) Adding or Removing columns: AddXXXToYYY attr1:type and RemoveXXXFromYYY attr1:type attr2:type
-
rails g migration AddStartDateToTask startdate:datetime
class AddStartDateToTask < ActiveRecord::Migration def change add_column :tasks, :start_date, :datetime end end
-
rails g migration RemoveStartdateFromTask startdate:datetime
class AddStartDateToTask < ActiveRecord::Migration def change remove_column :tasks, :start_date, :datetime end end
3.) You are not limited to one magically generated column. You can add multiple things at one time:
-
rails g migration AddDetailsToTasks attr1:type attr2:type attr3:type
class AddStartDateToTask < ActiveRecord::Migration def change add_column :tasks, :attr1, :type add_column :tasks, :attr2, :type add_column :tasks, :attr3, :type end end
4.) You can also add a reference to a table
-
rails g migration AddReftoTasks category:references
class AddUserRefToTasks < ActiveRecord::Migration def change add_reference :tasks, :category, index: true, foreign_key: true end end
5.) You can make a join table
rails g migration CreateJoinTableCustomerProduct customer product
class CreateJoinTableCustomerProduct < ActiveRecord::Migration
def change
create_join_table :customers, :products do |t|
#t.index [:customer_id, :product_id]
#t.index [:product_id, :customer_id]
end
end
end
6.) If you run an "empty" migration, rails g migration AddDetailsToProducts
, Then you will get a blank migration file. "Empty" meaning you did not include any attributes to add at the end of the command.
class AddDetailsToProducts < ActiveRecord::Migration
def change
end
end
Each command in the migration file with execute a statement in SQL written to our database. For example:
create_table :tasks do |t|
t.text :title
t.string :description
end
will generate some SQL similar to: CREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar);
If you want to see the sql written after you've migrated you can see it in the environments log file. For development it would be development.log
in the log
directory.
When we think about migrations, or making changes to a database, we can do and undo them. That is, if we create a table, we can drop a table. If we add a column then we can drop that column. When we use the change
method for our migration, Rails is smart enough to know the inverse of the method you used to alter the structure of the database. So, if you use the add_column
method, Rails know on rake db:rollback
to run the remove_column
method. Using the change
method is the same as using self.up
and add_column
and having a self.down
with remove column
. These two migration are the same thing:
class AddDetailsToProducts < ActiveRecord::Migration
def change
add_column :quantity, :integer
end
end
and
class AddDetailsToProducts < ActiveRecord::Migration
def self.up
add_column :quantity, :integer
end
def self.down
remove_column :quantity, :integer
end
end
The change method for ActiveRecord Migrations doesn't know how to do the opposite of every method. The ones it down know are the following:
- 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_column (must supply a type)
- remove_foreign_key (must supply a second table)
- remove_index
- remove_reference
- remove_timestamps
- rename_column
- rename_index
- rename_table