Rails 5.2 加载顺序中断 db:create

Rails 5.2 load order breaks db:create

我有一个 rails 应用程序,在 Rails 5.1 上创建 MySQL 数据库模式没有问题,但在升级到 Rails 5.2 后无法创建。

似乎在 5.2 中它会尝试在创建数据库之前加载所有模型、观察者、sphinx 索引等,而在 5.1 中它会先以某种方式创建数据库。

我认为任何特定的 gem 或初始值设定项都没有问题。我试图消除一些像 observers 只是为了看看它是否有任何效果但无济于事。

当 运行 5.1 显示如下:

$ rails db:create
...
Connected, but database does not exist: Unknown database '3scale_system_development'
Database '3scale_system_production' already exists
Created database '3scale_system_development'
Database '3scale_system_test' already exists
...

5.2 是

Connected, but database does not exist: Unknown database '3scale_system_development'
rake aborted!
ActiveRecord::NoDatabaseError: Unknown database '3scale_system_development'
/home/user/ws/repos/porta/app/indices/account_index.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/user.rb:21:in `<class:User>'
/home/user/ws/repos/porta/app/models/user.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:48:in `<class:EmailTemplate>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:42:in `block (2 levels) in <module:Provider>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:10:in `block in <module:Provider>'
/home/user/ws/repos/porta/app/models/account.rb:34:in `include'
/home/user/ws/repos/porta/app/models/account.rb:34:in `<class:Account>'
/home/user/ws/repos/porta/app/models/account.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:4:in `<class:AccountObserver>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/config/environment.rb:6:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'

Caused by:
Mysql2::Error: Unknown database '3scale_system_development'
/home/user/ws/repos/porta/app/indices/account_index.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/user.rb:21:in `<class:User>'
/home/user/ws/repos/porta/app/models/user.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:48:in `<class:EmailTemplate>'
/home/user/ws/repos/porta/app/models/cms/email_template.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:42:in `block (2 levels) in <module:Provider>'
/home/user/ws/repos/porta/app/lib/logic/cms.rb:10:in `block in <module:Provider>'
/home/user/ws/repos/porta/app/models/account.rb:34:in `include'
/home/user/ws/repos/porta/app/models/account.rb:34:in `<class:Account>'
/home/user/ws/repos/porta/app/models/account.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:4:in `<class:AccountObserver>'
/home/user/ws/repos/porta/app/observers/account_observer.rb:3:in `<top (required)>'
/home/user/ws/repos/porta/config/environment.rb:6:in `<top (required)>'
bin/rails:4:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:create => db:load_config => environment
(See full trace by running task with --trace)

知道会是什么吗?如果需要,您可以签出实际代码。

这是项目的 5.1 版本: https://github.com/3scale/porta/commit/33cc4d5bcb5910295bfa28d84416ff05e1a606f3(目前 master 分支)

这是5.2升级版: https://github.com/3scale/porta/commit/d75feac5cde9e085d5fdb2baa42c1fed674fceb8(目前 rails 分支)

我发现了导致问题的不同之处。在 5.1.7:

  task :load_config do
    ActiveRecord::Base.configurations       = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
    ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
  end

5.2.7中:

  task load_config: :environment do
    ActiveRecord::Base.configurations       = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
    ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
  end

db:create 任务依赖于 db:load_config 任务。在 5.2 中,db:load_config 任务依赖于 environment,它将应用程序加载所有观察者、sphinx 索引和诸如此类的东西,当 DB 尚不存在时会触发无法建立的 DB 连接。

我不知道我是否可以相当轻松地为我的应用修复此问题,但它至少回答了两者之间有何区别的问题。

这是在 https://github.com/rails/rails/pull/31135

中引入的

而且修复起来相对简单。您可以输入 Rakefile:

Rake::Task['db:load_config'].clear_prerequisites