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