New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rails 7: issues reloading a class that uses delegate_missing_to and references other class #44125
Comments
Adding the following (somewhat obviously) circumvents the issue: def respond_to_missing?(name, include_private = false)
return false if name == :before_remove_const
super
end |
I missed this one! Your analysis is correct. You didn't find this in 6.1 because This one is a bit tricky. Unloading is documented to happen in an undefined order. Documentation also says that, in consequence, However, your code is so far away from all this!
Let me think a bit about it. @casperisfine In my benchmarks, (1) is executed at about 874K i/s, do you think it would be noticeable at your scale? |
Another option is to eliminate this feature. It was missing in Rails 6.0 and Rails 6.1, nobody complained. It is not documented anywhere, only in a CHANGELOG of 3.1. Rails only uses it to reset AR scopes. Also, I don't like it. I don't like infra code mixed with business logic APIs, prefer callbacks (that is why Zeitwerk does not have this feature). |
Rails 6.0 and Rails 6.1 didn't support the undocumented `before_remove_const` in `zeitwerk` mode. I noticed this cleanup in AR was not being executed, and restored the original code for Rails 7. However, invoking `respond_to?` in an `on_unload` callback may have unexpected side-effects, as seen in #44125. So, this patch reimplements the cleanup in a more modern way. Fixes #44125.
I have backported the fix to @casperisfine please disregard the question :). |
Just in case, to round it, I have also added a mention to |
Rails Master, Ruby 3.1.0
In my app, I have
app/models/test_inventory.rb
defined as follows:The first boot / render works fine, but once I make a code change and zeitwerk tries to reload, I hit the following error:
I believe what's happening is that:
Item
class prior to unloading TestInventoryon_unload
for the TestCatalog class, it hits thevalue.respond_to?(:before_remove_const)
respond_to_missing?
logic provided bydelegate_missing_to
, which ultimately callsrespond_to?
on the delegated-to object, which calls thecatalog
method, which referencesItem
, which has been unloadedFYI: this is working for us on Rails 6.1; perhaps some ordering thing changed somewhere between then and 7.1/master?
The text was updated successfully, but these errors were encountered: