在Rails控制台中运行迁移

85

有没有一种在控制台上运行rake命令以进行db:migrate和db:rollback的方法?

等待Rails环境加载真的很烦人!

9个回答

125

在控制台中:

ActiveRecord::Migration.remove_column :table_name, :column_name

从控制台运行迁移后,要更新schema.rb文件,您必须运行rails db:migrate


@WestonGanger 怎么做? - nruth
1
@nruth 不确定weston在这里是否正确。我发现每次运行这些命令时,可能需要执行reload!才能在控制台中生效,并且在完成控制台操作后,只要退出控制台,我就会执行rails db:migrate,并迁移它们,并更新db/schema.rb。查看db/schema.rb非常好。它显示了所有的表格。rails db:migrate会为您更新schema.rb,至少我认为是这样。 - barlop
@WestonGanger 有什么评论吗?(因为您的评论正在受到质疑) - barlop
1
@barlop @nruth。当运行此命令时,迁移将立即发生并更改数据库,但模式不会更新。运行rails db:migrate可以自动更新模式。但这是一个额外的步骤,不在答案中。 - Weston Ganger
@WestonGanger 是的,但是由于您可以执行rails db:migrate命令,这并不是手动更新schema.rb文件。这是自动更新。 - barlop

89

Rails <= 4

这将允许您在不重新加载整个Rails环境的情况下进行迁移:

ActiveRecord::Migrator.migrate "db/migrate"

回滚操作:

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

Rails >= 5(感谢 @gssbzn,他的答案在下面)

迁移:

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

回滚操作:

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

2
请注意,如果您正在使用Mongoid,那么它是相同的:Mongoid::Migrator.migrate“db/migrate” - Josh Leitzel
收到错误,bash: ActiveRecord::Migrator.migrate: 命令未找到... 使用 Rails 2.3.18,ruby 1.9.3p551,在执行命令后现在在 Rails 控制台内执行。 - vidur punj
如果因为某些奇怪的原因你的迁移不在 'db/migrate' 目录中,可以使用 ActiveRecord::Tasks::DatabaseTasks.migrations_paths 来代替。 - user2384183
1
这对于Rails 4是正确的,但对于后续版本则不起作用。 - Shai Coleman
1
对于较新的Rails版本,您还需要传递 schema_migration 参数:ActiveRecord::MigrationContext.new(ActiveRecord::Migrator.migrations_paths, ActiveRecord::Base.connection.schema_migration) - pamit
显示剩余4条评论

32

我认为更简洁的方法是从控制台运行一些迁移命令:

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

这样做的好处是,区块内的内容可以与从真实迁移文件/ schema.rb 随意复制粘贴的内容兼容。


我发现这对于诊断迁移中的一些特定于数据库的问题非常有帮助。谢谢! - AJFaraday

14

对于Rails 5和Rails 6:

ActiveRecord::Base.connection.migration_context.migrate

对于Rails 3和Rails 4:

ActiveRecord::Migrator.migrate 'db/migrate'

这是Rails 5和6的最佳答案,因为它使用现有的方法来获取迁移上下文(直接实例化可能不可靠)。 - Kelvin

13

对于Rails 5.2,已删除接受的答案,并进行了替换。

ActiveRecord::MigrationContext.new("db/migrate").migrate
请注意,随着Rails致力于添加多个数据库连接,这也可能会在未来版本中发生变化。

7

我需要模拟一次迁移以解除部署阻塞,可以使用以下方法:

class Mig < ActiveRecord::Base; self.table_name = 'schema_migrations';end
Mig.create! version: '20180611172637'

5
你可以使用 %x[command] 命令。
%x[rake db:migrate]

3
这样做与避免等待载入Rails的目的背道而驰。 - rafamvc
@rafamvc 是的,我同意!这就是为什么我认为 Benoit 的回答更好 :) - dexter

1

运行单个迁移

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

运行所有迁移

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

回滚 n 个迁移

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


0
我在我的.irbrc文件中创建了一个方法,该方法运行迁移,然后重新加载控制台:
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

在此处查看完整文件:https://gist.github.com/imme5150/6548368


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接