Background:
I am getting some reloading errors in development when switching to Zeitwerk for a rails 6.0 application that uses an engine (thredded). I'm also a developer on thredded, so want to understand this fully before committing any apparent fixes:
I've already read:
- https://guides.rubyonrails.org/autoloading_and_reloading_constants
- https://guides.rubyonrails.org/engines.html#overriding-models-and-controllers (and implemented these fixes in the main app)
- https://github.com/fxn/zeitwerk/blob/main/README.md (amazingly informative)
- https://github.com/fxn/zeitwerk/issues/143
First Question (separation of autoloading and engines): Are engines autoloaded in the same zeitwerk instance/loader as the main app, or are they somehow loaded separately? That is to say does wrapping some code with Rails.application.reloader.to_prepare do
ensure that code is run before both the main app and the engine are reloaded.
Second Question (engine code reloading): Are engine's constants reloaded when the main app reloads? (my understanding is yes).
Third Question (configuring engines): Currently Thredded's docs suggest that the configuration of Thredded happens in an initializer -- e.g. Thredded.some_configuration_option = value
- but I think that would get wiped away with autoloading? So therefore probably needs to be wrapped with (I think) Rails.application.reloader.to_prepare do
(but this isn't what e.g. Devise recommends (see https://github.com/heartcombo/devise/blob/main/lib/generators/templates/devise.rb) and seems to conflict with https://github.com/fxn/zeitwerk/issues/143). What have I misunderstood here?
Fourth Question (all these to_prepares): Can someone explain or point me to docs that clarify the lifecycle difference between:
Rails.application.reloader.to_prepare do
(and is the block run at least once even when it is eager loaded in production with reloading on)Rails.application.config.to_prepare do
SomeEngine::Engine.config.to_prepare do
Any answers would be great. Kind of a long Q with multiple parts. Happy to split this into multiple StackOverflow Qs if appropriate but they seem quite linked.
Thredded
constant is not reloadable, it is defined inlib/thredded.rb
, which is a top-level file required. Only what is in the enginesapp
directory is autoloaded and reloaded (by default, don't see anything special configured). (4) The existing config.to_prepare seems good to me and is what you want to use. What problem do you have exactly? – Fivespotreset_instance!' for Thredded::AllViewHooks:Class", then (if I refresh the page again) "undefined method
thredded_can_moderate_messageboards' for #<User:0x00007f89b28bf5e0>"). Maybe something to do with the way that Thredded extends the main app's User class with Thredded::UserExtender maybe? -- github.com/thredded/thredded/blob/…) – Hagride