是否有可用的插件让Rails在启动时运行db:migrate?我正在寻找一种不涉及通过shell调用Rake任务的解决方案;所以,没有“system('rake db:migrate')
”。
我可以随时编写自己的插件来执行此操作,但我认为如果存在一个现有的migrate-on-init插件会更好。
答案 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
有效,但有两个问题:
它在所有其他初始化程序之后运行,因此如果这些初始化程序执行某些数据库操作,则它们将使用旧模式
它可以在所有环境中运行,包括Rake任务和Resque worker。我们不希望每次运行rake routes
时都自动迁移,是吗?我们不希望同时发生多次迁移。
我的解决方案是使用config/initializers
文件,这样我就可以决定它运行的顺序,并检查我们是否在rake任务中。
此外,在我熟悉部署时自动迁移之前,我只会在development
和test
环境中执行此操作。
最后,我想要打印一些额外的信息(迁移到版本和从版本迁移),所以我没有使用单行程序,而是进入迁移器,可能比我应该更加密切。
噢,是的!它也应该写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例程是资源和时间浪费。