Home > Blockchain >  Rails Model no longer available in initializer after upgrade to Rails 7.0
Rails Model no longer available in initializer after upgrade to Rails 7.0

Time:08-24

I have a Rails initializer (features.rb) that must access a model (Report).

Report.all.each do |report|
  default_to_enabled(report&.feature_name)
end

This all worked perfectly with Rails 6.1 using Zeitwerk and defaults set for 6.1:

config.load_defaults 6.1
config.autoloader = :zeitwerk

But upgrading to Rails 7, keeping defaults at 6.1 (and obviously using Zeitwerk), it is not working:

/Users/brandon/Code/Rails/portal/config/initializers/features.rb:105:in `<main>': uninitialized constant Report (NameError)

If I manually require the Report model, it doesn't solve the problem. Instead I just get

/Users/brandon/Code/Rails/portal/app/models/report.rb:1:in `<main>': uninitialized constant ApplicationRecord (NameError)
Did you mean?  ApplicationConfig

So it seems like there's a whole lot of stuff that has not yet been loaded at this point in the Rails boot-up process, but which would have been loaded at this point running on Rails 6.1.

Adding require 'rails/all' doesn't change anything.

(In case it's not obvious, this applies to all of my models, and lots of other things. None of the classes I have previously had available during initialization are now available on Rails 7.)

How can I fix this and make everything work on Rails 7?

CodePudding user response:

While poking around in the Autoloading guide it occurred to me to try this in config/application.rb:

config.autoload_once_paths << "#{root}/app/models"

but while that made my Report class available, it also created a bigger new problem with Zeitwerk.

The only thing I've found so far is to work around the limitation rather than try to resolve it (or one might say "work with the grain instead of against it") by adding this in config/application.rb instead of the code in my initializer:

config.after_initialize do
  Report.all.each do |report|
    default_to_enabled(report&.feature_name)
  end      
end

CodePudding user response:

No, autoload_once_paths is not what you want, because reloading won't update the models.

Please, read this section of the autoloading guide.

  • Related