Home > Software design >  Rails 5.2 load order breaks db:create
Rails 5.2 load order breaks db:create

Time:05-11

I have a rails application that on Rails 5.1 had no troubles creating MySQL db schemas but fails to create after upgrading to Rails 5.2.

It seems like with 5.2 it tries to load all models, observers, sphinx indexes, etc. before creating the databases while with 5.1 it somehow created databases first.

I don't think issue is with any particular gem or initializer. I tried to eliminate some like observers just to see if it made any difference to no avail.

When running with 5.1 it shows something like:

$ 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
...

With 5.2 it is

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)

Any idea what could it be? You can checkout the actual code if needed.

This is 5.1 version of the project: https://github.com/3scale/porta/commit/33cc4d5bcb5910295bfa28d84416ff05e1a606f3 (presently master branch)

This is 5.2 upgraded version: https://github.com/3scale/porta/commit/d75feac5cde9e085d5fdb2baa42c1fed674fceb8 (presently rails branch)

CodePudding user response:

I found the difference causing the issue. In 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

In 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

The db:create task depends on the db:load_config task. In 5.2 the db:load_config task depends on environment, which loads the application with all observers, sphinx indices and whatnot, which trigger a DB connection that can't be established when DB does not yet exist.

I don't know if I can reasonably easy fix this for my app but it at least answers the question what was the difference between the two.

This was introduced with https://github.com/rails/rails/pull/31135

And is relatively straightforward to fix. You can put in your Rakefile:

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