Skip to content

Conversation

@mshibuya
Copy link
Contributor

@mshibuya mshibuya commented Feb 5, 2022

I'm trying to use turbo-rails in our project, but with JRuby and Rails 6.1 the Rails app fails to start with emitting the following error:

rake aborted!
NoMethodError: undefined method `do_not_eager_load' for nil:NilClass
/home/runner/work/rails_admin/rails_admin/vendor/bundle/jruby/2.6.0/gems/turbo-rails-1.0.1/lib/turbo/engine.rb:20:in `block in Engine'
/home/runner/work/rails_admin/rails_admin/vendor/bundle/jruby/2.6.0/gems/railties-6.1.4.4/lib/rails/initializable.rb:32:in `run'
/home/runner/work/rails_admin/rails_admin/vendor/bundle/jruby/2.6.0/gems/railties-6.1.4.4/lib/rails/initializable.rb:61:in `block in run_initializers'
/home/runner/work/rails_admin/rails_admin/vendor/bundle/jruby/2.6.0/gems/railties-6.1.4.4/lib/rails/initializable.rb:50:in `tsort_each_child'
...

https://github.com/railsadminteam/rails_admin/runs/4995149973?check_suite_focus=true

What I found was that Rails 6.1 with JRuby doesn't enable the Zeitwerk by default, which results in the value of Rails.autoloaders.once to be nil.
https://github.com/rails/rails/blob/6-1-stable/railties/lib/rails/autoloaders.rb#L19-L26

So my fix here is to call do_not_eager_load only if Zeitwerk is enabled. This will prevent stopping eager-load of files under app/channels/turbo/ in non-Zeitwerk environment, but for most of users it won't be a problem because they should have ActionCable loaded in a normal Rails setup. Or if there's a better implementation I'd be glad to adopt it.

Thanks in advance!

@gaganawhad
Copy link

gaganawhad commented Mar 2, 2022

We are using Rails 6.1 and Ruby 2.7.5 with rails_admin and are experiencing the same issue. Just wanted to +1 This PR. Eager to hear if there is a better solution. I would like to not load Action Cable just to get by this issue, given that we are not using it.


initializer "turbo.no_action_cable" do
Rails.autoloaders.once.do_not_eager_load(Dir["#{root}/app/channels/turbo/*_channel.rb"]) unless defined?(ActionCable)
Rails.autoloaders.once.do_not_eager_load(Dir["#{root}/app/channels/turbo/*_channel.rb"]) if !defined?(ActionCable) && Rails.autoloaders.zeitwerk_enabled?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this fix the problem? If zetiwerk is disable and action cable is not present, the action cable files would still be loaded. We need to teach the classic autoload to not load this code as well when zeitwerk is not enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the purpose of this fix is not to stop autoloading the code, but to fix breaking with NoMethodError.
Loading things what might be unnecessary is trivial, compared to completely breaking the classic-autoloader application.

And I couldn't find a way to

teach the classic autoload to not load this code

, but do you have any idea on it?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think maybe paths["app/channel"].clear? I think that would fix in both modes and not need to check if zeitwerk is enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. The given one ended up with:

/path/to/turbo-rails/lib/turbo/engine.rb:22:in `block in <class:Engine>': undefined method `clear' for #<Rails::Paths::Path:0x00000001348f1198 @paths=["app/channels"], ...>

but I managed to write an implementation which works with both Zeitwerk and the classic autoloader.
Please kindly check.

Change the implementation to support both Zeitwerk and the classic autoloader
@mshibuya mshibuya force-pushed the fix/breaking-in-non-zeitwerk-env branch from c72adf8 to 713864f Compare March 26, 2022 09:45
@dhh dhh merged commit 0178d18 into hotwired:main May 3, 2022
@mshibuya mshibuya deleted the fix/breaking-in-non-zeitwerk-env branch May 4, 2022 03:27
dhh added a commit to ankurp/turbo-rails that referenced this pull request May 22, 2022
* main: (175 commits)
  Support `[formmethod]` overrides to `_method` (hotwired#239)
  call ActionView::RecordIdentifier.dom_id explicitly (hotwired#333)
  removed a handful of extra 'the' in method descriptions (hotwired#334)
  Fix missing `activejob` dependency (hotwired#331)
  Document the turbo_frame_tag helper with multiple arguments (hotwired#329)
  Add possibility to nest turbo frames (hotwired#296)
  Fix breaking in non-Zeitwerk environment (hotwired#304)
  Problem: inability to pass additional parameters to stream channels (hotwired#308)
  Fix CI with Rails main (hotwired#314)
  add targets to assert_{,no_}turbo_stream (hotwired#321)
  fix tests for rails 7.0 (hotwired#320)
  Test on Rails 7.0
  Use where on Windows instead of which (hotwired#299) (hotwired#300)
  Bump version for 1.0.1
  Upgrade @rails/actioncable to 7.0.1
  Bump @rails/actioncable dependency to ^7.0
  Add Turbo::Broadcastable support for #broadcast_render and #broadcast_render_to (hotwired#298)
  fix a little typo for wrong constant name (hotwired#290)
  Bump version for 1.0.0
  Make clear this is included by default in Rails 7
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants