Rails插件在启动时运行迁移?

时间:2009-04-12 23:55:22

标签: ruby-on-rails

是否有可用的插件让Rails在启动时运行db:migrate?我正在寻找一种不涉及通过shell调用Rake任务的解决方案;所以,没有“system('rake db:migrate')”。

我可以随时编写自己的插件来执行此操作,但我认为如果存在一个现有的migrate-on-init插件会更好。

5 个答案:

答案 0 :(得分:3)

这是我在jRuby上的Rails 3.2的工作版本:

config.after_initialize do
  ActiveRecord::Migrator.migrate(Rails.root.join("db/migrate"), nil)
end

答案 1 :(得分:2)

将以下内容放在environment.rb中的Rails :: Initializer块中......

  config.after_initialize do
    ActiveRecord::Migrator.migrate (RAILS_ROOT + "/db/migrate" )
  end

答案 2 :(得分:2)

使用config.after_initialize有效,但有两个问题:

  1. 它在所有其他初始化程序之后运行,因此如果这些初始化程序执行某些数据库操作,则它们将使用旧模式

  2. 它可以在所有环境中运行,包括Rake任务和Resque worker。我们不希望每次运行rake routes时都自动迁移,是吗?我们不希望同时发生多次迁移。

  3. 我的解决方案是使用config/initializers文件,这样我就可以决定它运行的顺序,并检查我们是否在rake任务中。

    此外,在我熟悉部署时自动迁移之前,我只会在developmenttest环境中执行此操作。

    最后,我想要打印一些额外的信息(迁移到版本和从版本迁移),所以我没有使用单行程序,而是进入迁移器,可能比我应该更加密切。

    噢,是的!它也应该写schema.rb。所以我公然从db:schema:dump内部active_record/railties/databases.rake窃取代码。 (如果rake任务是对象上的方法,那么我们可以调用它们,这不是很好吗?)

    config/initializers/automatically_migrate.rb

    # don't do this in production
    if (Rails.env.development? or Rails.env.test?) and
        # don't do this in a worker or task
        !defined?(Rake)  # SEE BELOW FOR POSSIBLE FIX
    
      migrations_paths = ActiveRecord::Migrator.migrations_paths
      migrator = ActiveRecord::Migrator.new(:up, migrations_paths, nil)
      pending_migrations = migrator.pending_migrations
      unless pending_migrations.empty?
        puts "Migrating from #{migrator.current_version} to #{pending_migrations.last.version}"
        migrator.migrate
    
        require 'active_record/schema_dumper'
        filename = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
        File.open(filename, "w:utf-8") do |file|
          ActiveRecord::Base.establish_connection(Rails.env)
          ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
        end
    
      end
    
    end
    

    更新:显然Rake的新版本在加载时更加自由,因此表达式!defined?(Rake)始终为false,即使从命令行运行(即不在Rake Task或Resque Worker中) )。我正在尝试以下

    caller.grep(/rake/).empty?
    

答案 3 :(得分:1)

Sam的答案对我来说并不适用。我正在使用Rails 3.0,我想你可能需要在application.rb中添加这个,在类中的任何地方。

config.after_initialize do
  ActiveRecord::Migrator.migrate (RAILS_ROOT + "/db/migrate" )
end

在类似的说明中,我正在使用JRuby和部署作为战争,我想知道为什么这不是为我创建表,而是抱怨表这样的&这样的不存在。

答案 4 :(得分:-2)

根据我的经验,只有在新的迁移存在时才应调用db:migrate-like例程,因为它需要相当多的时间。你不应该真的有这么多的迁移,当它们存在时你无法追踪。

也就是说,在生产环境中运行新迁移的任务最好由Capistrano等部署工具处理。当部署到生产箱时,如果您也说明,capistrano会运行迁移。

在每个init上运行db:migrate-like例程是资源和时间浪费。