84

Is there a way to run rake commands for db:migrate and db:rollback on the console?

It sucks to wait for the rails environment to load!

rafamvc
  • 8,227
  • 6
  • 31
  • 34

9 Answers9

122

In the console:

ActiveRecord::Migration.remove_column :table_name, :column_name

To update your schema.rb file after running migrations from the console, you must run rails db:migrate

Weston Ganger
  • 6,324
  • 4
  • 41
  • 39
Homan
  • 25,618
  • 22
  • 70
  • 107
  • @WestonGanger how? – nruth Feb 10 '18 at 13:46
  • 1
    @nruth not sure that weston is correct here. I find that any time I run these commands, then I might have to do `reload!` to get the effect in the console, and having finished with the console, as long I exit the console, I do rails db:migrate, and it migrates them, and updates db/schema.rb . Really good to look at db/schema.rb . it shows all your tables. `rails db:migrate` updates `schema.rb` for you, at least I think that's what i've found. – barlop Apr 18 '19 at 15:12
  • @WestonGanger care to comment?(as your comment is under question) – barlop Apr 18 '19 at 15:43
  • 1
    @barlop @nruth. The migration occurs as soon as this command is run and changes the database, the schema however will not be updated. Running `rails db:migrate` can automatically update the schema. However this is an extra step that is not in the answer. – Weston Ganger Apr 19 '19 at 16:25
  • @WestonGanger yeah but since you can do rails db:migrate, that's not manually updating the schema.rb file. That's automatically updating it. – barlop Apr 19 '19 at 19:00
89

Rails <= 4

This will allow you to migrate without reloading the whole rails environment:

ActiveRecord::Migrator.migrate "db/migrate"

and rollback:

# 3 is the number of migrations to rollback, optional, defaults to 1
ActiveRecord::Migrator.rollback "db/migrate", 3

Rails >= 5 (thanks to @gssbzn, his answer is below)

Migrate :

ActiveRecord::MigrationContext.new("db/migrate").migrate

And rollback :

# 3 is the number of migrations to rollback, optional, defaults to 1
ActiveRecord::MigrationContext.new("db/migrate").rollback 3
Noach Magedman
  • 2,313
  • 1
  • 23
  • 18
Benoit Garret
  • 14,027
  • 4
  • 59
  • 64
  • 2
    Note that if you're using Mongoid, it's the same: `Mongoid::Migrator.migrate "db/migrate"` – Josh Leitzel Sep 05 '12 at 18:00
  • This is perfect to add to your test_helper.rb in Rails apps – Weston Ganger Oct 07 '16 at 19:28
  • Received error, bash: ActiveRecord::Migrator.migrate: command not found... using Rails 2.3.18, ruby 1.9.3p551, Now executed after executing the command inside the rails console. – vidur punj Feb 01 '18 at 11:26
  • In case for some weird reasons your migrations aren't located in `'db/migrate'`, use `ActiveRecord::Tasks::DatabaseTasks.migrations_paths` in its place –  Feb 15 '18 at 02:43
  • 1
    This is correct for Rails 4, but doesn't work for later versions – Shai Coleman Jan 30 '20 at 17:35
  • See @gssbzn's answer for compatibility with rails 5.2+ – mikemachado Apr 28 '20 at 21:03
  • Rollback for above 5 - `ActiveRecord::MigrationContext.new("db/migrate").rollback` - not mentioned but also works – oklas Jun 03 '20 at 12:00
  • This worked for Rails 5 using this command ActiveRecord::Migrator.migrate "db/migrate" – Taimoor Changaiz Jul 11 '20 at 09:29
  • 1
    For newer Rails versions, you also need to pass `schema_migration`: `ActiveRecord::MigrationContext.new(ActiveRecord::Migrator.migrations_paths, ActiveRecord::Base.connection.schema_migration)` – pamit Mar 17 '21 at 05:35
31

Another way that I find neater to just run some migration command from console is this:

ActiveRecord::Schema.define do
  create_table :foo do |t|
    t.string  :bar
    t.timestamps
  end
end

This has the advantage that the contents inside the block is compatible with just copy and pasting random contents from a real migration file / schema.rb.

kizzx2
  • 18,775
  • 14
  • 76
  • 83
13

For rails 5.2 the accepted answer has been removed and replaced with

ActiveRecord::MigrationContext.new("db/migrate").migrate

Please be aware as this may also change for future versions of rails as they work to add multiple database connections

Gus
  • 141
  • 2
  • 5
13

For Rails 5 and Rails 6:

ActiveRecord::Base.connection.migration_context.migrate

For Rails 3 and Rails 4:

ActiveRecord::Migrator.migrate 'db/migrate'
Shai Coleman
  • 868
  • 15
  • 17
  • This is the best answer for Rails 5 & 6, because it uses existing methods to get the migration context (instantiating it directly may not be reliable). – Kelvin Jan 05 '22 at 17:19
6

I needed to pretend a migration was run to unblock a deploy, this can be done with:

class Mig < ActiveRecord::Base; self.table_name = 'schema_migrations';end
Mig.create! version: '20180611172637'
grosser
  • 14,707
  • 7
  • 57
  • 61
5

You can use the %x[command]

%x[rake db:migrate]
dexter
  • 13,365
  • 5
  • 39
  • 56
1

To run single migration

ActiveRecord::Migration.add_column(:table_name, :column_name, :data_type)

To run all migrations

ActiveRecord::Migrator.migrate('db/migrate')

To rollback n migrations

ActiveRecord::Migrator.rollback('db/migrate', n)

Rakesh
  • 793
  • 4
  • 22
0

I created a method in my .irbrc file that runs migrations then reloads the console:

def migrate
  if defined? Rails::Console # turn off info logging for Rails 3
    old_log_level = ActiveRecord::Base.logger.try(:sev_threshold)
    ActiveRecord::Base.logger.sev_threshold = Logger::WARN
  end
  reload! && migations_ran = true if ActiveRecord::Migrator.migrate(Rails.root.join("db/migrate")).any?
  ActiveRecord::Base.logger.sev_threshold = old_log_level if defined? old_log_level
  migations_ran ||= nil # useful exit status
end

See the entire file here: https://gist.github.com/imme5150/6548368

Josh
  • 8,329
  • 4
  • 36
  • 33