class AddReceiveNewsletterToUsers < ActiveRecord::Migration
def self.up
change_table :users do |t|
t.boolean :receive_newsletter, :default => false
end
User.update_all ["receive_newsletter = ?", true]
end
def self.down
remove_column :users, :receive_newsletter
end
end
- create_table
- change_table
- drop_table
- add_column
- change_column
- rename_column
- remove_column
- add_index
- remove_index
You must rollback the migration (for example with
rake db:rollback
), edit your migration and then run
rake db:migrate
to run the corrected version.
Instead you should write a new migration that performs the changes you require.
rails generate migration AddDetailsToProducts part_number:string price:decimal
class AddDetailsToProducts < ActiveRecord::Migration
def self.up
add_column :products, :part_number, :string
add_column :products, :price, :decimal
end
def self.down
remove_column :products, :price
remove_column :products, :part_number
end
end
You can change the name of the primary key with the :primary_key option (don’t forget to update the corresponding model) or if you don’t want a primary key at all (for example for a HABTM join table) you can pass :id => false. If you need to pass database specific options you can place an SQL fragment in the :options option.
create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
t.string :name, :null => false
end
The types supported by Active Record are :primary_key, :string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean.
You can create columns of types not supported by Active Record when using the non-sexy syntax, for example
create_table :products do |t|
t.column :name, 'polygon', :null => false
end
change_table :products do |t|
t.remove :description, :name
t.string :part_number
t.index :part_number
t.rename :upccode, :upc_code
end
class ExampleMigration < ActiveRecord::Migration
def self.up
create_table :products do |t|
t.references :category
end
#add a foreign key
execute <<-SQL
ALTER TABLE products
ADD CONSTRAINT fk_products_categories
FOREIGN KEY (category_id)
REFERENCES categories(id)
SQL
add_column :users, :home_page_url, :string
rename_column :users, :email, :email_address
end
def self.down
rename_column :users, :email_address, :email
remove_column :users, :home_page_url
execute "ALTER TABLE products DROP FOREIGN KEY fk_products_categories"
drop_table :products
end
end
Sometimes your migration will do something which is just plain irreversible, for example it might destroy some data. In cases like those when you can’t reverse the migration you can raise IrreversibleMigration from your down method. If someone tries to revert your migration an error message will bedisplayed saying that it can’t be done.
rake db:migrate VERSION=20080906120000
rake db:rollback
rake db:rollback STEP=3
rake db:migrate:redo STEP=3
Lastly, the db:reset task will drop the database, recreate it and load the current schema into it.
rake db:migrate:up VERSION=20080906120000
For performance reasons information about the columns a model has is cached. For example if you add a column to a table and then try and use the corresponding model to insert a new row it may try to use the old column information. You can force Active Record to re-read the column information with the reset_column_information method, for example
class AddPartNumberToProducts < ActiveRecord::Migration
class Product < ActiveRecord::Base
end
def self.up
add_column :product, :part_number, :string
Product.reset_column_information
...
end
def self.down
...
end
end