Rails плагин для запуска миграций при запуске? - PullRequest
3 голосов
/ 13 апреля 2009

Есть ли плагин для запуска Rails через db: migrate при запуске? Я ищу решение, которое не требует вызова задачи Rake через оболочку; Итак, нет "system('rake db:migrate')".

Я могу с готовностью написать свой собственный плагин для этого, но подумал, что было бы лучше использовать / улучшить существующий плагин migrate-on-init, если он существует.

Ответы [ 5 ]

3 голосов
/ 25 июля 2012

Вот моя рабочая версия для Rails 3.2 на jRuby:

config.after_initialize do
  ActiveRecord::Migrator.migrate(Rails.root.join("db/migrate"), nil)
end
2 голосов
/ 07 сентября 2012

Использование config.after_initialize работает, но есть две проблемы:

  1. он запускается после всех других инициализаторов, поэтому, если эти инициализаторы выполняют какие-то операции с базами данных, они будут использовать старую схему

  2. он работает во всех средах, включая задачи Rake и работников Resque. Мы не хотим автоматически мигрировать каждый раз, когда запускаем rake routes, не так ли? И мы не хотим, чтобы множественные миграции происходили одновременно.

Мое решение состоит в том, чтобы использовать файл config/initializers, чтобы я мог решить, в каком порядке он запускается, и проверить, не находимся ли мы в грабли.

Кроме того, до тех пор, пока я не освою автоматическую миграцию при развертывании, я делаю это только в средах development и test.

Наконец, я хочу напечатать некоторую дополнительную информацию (переход на версию и обратно), поэтому вместо однострочного я получаю доступ к Мигратору, возможно, более тесно, чем следовало бы.

Ах да! Также следует написать schema.rb. Так что я нагло краду код из db:schema:dump изнутри active_record/railties/databases.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) всегда ложно, даже если оно запускается из командной строки (т.е. не внутри Rake Task или Resque Worker). Вместо этого я пробую следующее

caller.grep(/rake/).empty?
2 голосов
/ 27 апреля 2009

Поместите следующее в блок Rails :: Initializer в environment.rb ...

  config.after_initialize do
    ActiveRecord::Migrator.migrate (RAILS_ROOT + "/db/migrate" )
  end
1 голос
/ 17 июня 2011

Ответ Сэма у меня не совсем сработал. Я использую Rails 3.0, думаю, вам может понадобиться добавить это в application.rb где-нибудь внутри класса.

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

В аналогичной заметке я использую JRuby и Deploying as War, мне интересно, почему это не создает таблицы для меня, вместо этого он жалуется, что таблица такая и такая не существует.

0 голосов
/ 26 апреля 2009

По моему опыту, db: migrate-like процедура должна вызываться только при наличии новых миграций, потому что это занимает довольно много времени. У вас не должно быть так много миграций, которые вы не сможете отследить, когда они присутствуют.

При этом задача запуска новой миграции в производственной среде лучше всего решается с помощью таких инструментов развертывания, как Capistrano. при развертывании в рабочей коробке capistrano запускает миграцию, если вы тоже это скажете.

Выполнение db: процедура, подобная переносу, для каждого init - это ресурс и время тратится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...