Is there an easy way to run a single migration? I don't want to migrate to a certain version I just want to run a specific one.
11 Answers
You can just run the code directly out of the ruby file:
rails console
>> require "db/migrate/20090408054532_add_foos.rb"
>> AddFoos.new.up
Note: Very old versions of rails may require AddFoos.up
rather than AddFoos.new.up
.
An alternative way (without IRB) which relies on the fact that require returns an array of class names:
script/runner 'require("db/migrate/20090408054532_add_foos.rb").first.constantize.up'
Note that if you do this, it won't update the schema_migrations
table, but it seems like that's what you want anyway.
Additionally, if it can't find the file you may need to use require("./db/..."
or try require_relative
depending on your working directory
Assuming fairly recent version of Rails you can always run:
rake db:migrate:up VERSION=20090408054532
Where version is the timestamp in the filename of the migration.
Edit: At some point over the last 8 years (I'm not sure what version) Rails added checks that prevent this from running if it has already been run. This is indicated by an entry in the schema_migrations
table. To re-run it, simply execute rake db:migrate:redo VERSION=20090408054532
instead.
If you want to run a specific migration, do
$ rake db:migrate:up VERSION=20080906120000
If you want to run migrations multiple times, do
# use the STEP parameter if you need to go more than one version back
$ rake db:migrate:redo STEP=3
If you want to run a single migration multiple times, do
# this is super useful
$ rake db:migrate:redo VERSION=20080906120000
(you can find the version number in the filename of your migration)
Edit: You can also simply rename your migration file, Eg:
20151013131830_my_migration.rb
-> 20151013131831_my_migration.rb
Then migrate normally, this will treat the migration as a new one (usefull if you want to migrate on a remote environment (such as staging) on which you have less control.
Edit 2: You can also just nuke the migration entry in the database. Eg:
rails_c> q = "delete from schema_migrations where version = '20151013131830'"
rails_c> ActiveRecord::Base.connection.execute(q)
rake db:migrate
will then rerun the up
method of the nuked migrations.
If you've implemented a change
method like this:
class AddPartNumberToProducts < ActiveRecord::Migration
def change
add_column :products, :part_number, :string
end
end
You can create an instance of the migration and run migrate(:up)
or migrate(:down)
on an instance, like this:
$ rails console
>> require "db/migrate/20090408054532_add_part_number_to_products.rb"
>> AddPartNumberToProducts.new.migrate(:down)
This are the steps to run again this migration file "20150927161307_create_users.rb"
- Run the console mode. (rails c)
Copy and past the class which is in that file to the console.
class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.string :name t.string :email t.timestamps null: false end end end end
Create an instance of the class
CreateUsers
:c1 = CreateUsers.new
- Execute the method
change
of that instance:c1.change
If you want to run it from console, this is what you are looking for:
$ rails console
irb(main)> require "#{Rails.root.to_s}/db/migrate/XXXXX_my_migration.rb"
irb(main)> AddFoo.migrate(:up)
I tried the other answers, but requiring without Rails.root
didnt work for me.
Also, .migrate(:up)
part forces the migration to rerun regardless if it has already run or not. This is useful for when you already ran a migration, have kinda undone it by messing around with the db and want a quick solution to have it up again.
Looks like at least in the latest Rails release (5.2 at the time of writing) there is one more way of filtering the migrations being ran. One can pass a filter in a SCOPE
environment variable which would be then used to select migration files.
Assuming you have two migration files 1_add_foos.rb
and 2_add_foos.run_this_one.rb
running
SCOPE=run_this_one rails db:migrate:up
will select and run only 2_add_foos.run_this_one.rb
. Keep in mind that all migration files matching the scope will be ran.