Skip to content
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

Lookup problems with gem which integrates zeitwerk #300

Closed
fschwahn opened this issue Aug 29, 2024 · 7 comments
Closed

Lookup problems with gem which integrates zeitwerk #300

fschwahn opened this issue Aug 29, 2024 · 7 comments

Comments

@fschwahn
Copy link

I'm using https://github.com/mbleigh/acts-as-taggable-on in a rails project (version 7.1.4 at the moment). I also use the pundit gem for authorization, and it expects that policies are defined as follows:
If I have a Post-model, it expects a PostPolicy-class to be defined which contains the authorization logic (see https://github.com/varvet/pundit?tab=readme-ov-file#policies for more).

acts-as-taggable-on has just released a new version, in which it adopts zeitwerk for autoloading (in this PR I believe: mbleigh/acts-as-taggable-on#1132).

So, in order to use pundit and acts-as-taggable-on together, I define a class named ActsAsTaggableOn::TagPolicy in my codebase. This works when the app initially boots, but as soon as code reloads, it can no longer find ActsAsTaggableOn::TagPolicy, raising a NameError (it's enough to open a console and issue a reload!). When I downgrade acts-as-taggable-on to before it switched to zeitwerk, the problem goes away.

Is this a fundamental limitation when a gem uses zeitwerk for autoloading itself, or is something off with how this was implemented in acts-as-taggable-on?

@fxn
Copy link
Owner

fxn commented Aug 30, 2024

Usage of Zeitwerk in that gem seems correct at first sight.

Could you please add Rails.autoloaders.log! to config/application.rb, reproduce, and share the traces?

@fschwahn
Copy link
Author

fschwahn commented Sep 2, 2024

Is it possible that it is connected to this custom inflection rule?

https://github.com/seuros/acts-as-taggable-on/blob/31f29c991e0cf6ec178e618be64e2b92f2f0b02e/lib/acts-as-taggable-on.rb#L6-L8

I truncated the log to only include the parts which I believe are relevant, I hope I didn't leave anything important out.

➜  app git:(master) ✗ rails c
Zeitwerk@rails.main: autoload set for ApplicationPolicy, to be loaded from /app/app/policies/application_policy.rb
Zeitwerk@rails.main: autoload set for ActsAsTaggableOn::TagPolicy, to be loaded from /app/app/policies/acts_as_taggable_on/tag_policy.rb
Running via Spring preloader in process 4414
Loading development environment (Rails 7.1.3.4)
irb(main):001> ActsAsTaggableOn::TagPolicy
Zeitwerk@rails.main: constant ApplicationPolicy loaded from file /app/app/policies/application_policy.rb
Zeitwerk@rails.main: constant ActsAsTaggableOn::TagPolicy loaded from file /app/app/policies/acts_as_taggable_on/tag_policy.rb
=> ActsAsTaggableOn::TagPolicy
irb(main):002> reload!
Reloading...
Zeitwerk@rails.main: ApplicationPolicy unloaded
Zeitwerk@rails.main: ActsAsTaggableOn::TagPolicy unloaded
Zeitwerk@rails.main: autoload set for ApplicationPolicy, to be loaded from /app/app/policies/application_policy.rb
  ActiveRecord::SchemaMigration Load (1.2ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  ActiveRecord::SchemaMigration Load (1.0ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
=> true
irb(main):003> ActsAsTaggableOn::TagPolicy
(irb):3:in `<main>': uninitialized constant ActsAsTaggableOn::TagPolicy (NameError)

ActsAsTaggableOn::TagPolicy
                ^^^^^^^^^^^
Did you mean?  StatsPolicy
               RatePolicy
irb(main):004> 

Notably, the line

Zeitwerk@rails.main: autoload set for ActsAsTaggableOn::TagPolicy, to be loaded from /app/app/policies/acts_as_taggable_on/tag_policy.rb

only appears on the initial app load, but not when reloading.

@fxn
Copy link
Owner

fxn commented Sep 2, 2024

In principle, the inflection rule looks good. The namespace ActsAsTaggableOn is not managed by the Rails loader.

Do the logs mention ActsAsTaggableOn saying that the namespace already exists? I am missing those traces.

@fschwahn
Copy link
Author

fschwahn commented Sep 2, 2024

There are a bunch of those messages, such as

Zeitwerk@rails.once: the namespace Turbo already exists, descending into /Users/fabian/.rbenv/versions/3.3.4/lib/ruby/gems/3.3.0/gems/turbo-rails-1.1.1/app/channels/turbo

However, there is no such message for ActsAsTaggableOn

@fxn
Copy link
Owner

fxn commented Sep 2, 2024

Cool, I could reproduce. Let me investigate.

@fxn
Copy link
Owner

fxn commented Sep 2, 2024

It was a bug, an edge case that happened specifically when 3rd party code reopened the main namespace of a gem dependency also managed by Zeitwerk.

I have released 2.6.18 with the fix. Can you give it a try?

@fschwahn
Copy link
Author

fschwahn commented Sep 2, 2024

2.6.18 fixes the issue - thanks for the quick turnaround!

@fschwahn fschwahn closed this as completed Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants