Skip to content

Autoloading helpers fails initially in Rails 7.x, but succeeds on the second attempt #43205

Closed
@bradgessler

Description

@bradgessler

Steps to reproduce

When I try loading a Rails Application in Ruby 7.0, the app/helpers autoload path does not appear to be working from my gems engine.

Here's the script to reproduce the issue NOT working under 7.0:

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "sitepress", github: "sitepress/sitepress", branch: "rails-7"
  gem "rails", github: "rails/rails", branch: "main"
end

require "sitepress/server"  # Load all the stuff needed setup the configuration below.

# Setup defaults for stand-alone Sitepress server in the current path. This
# can, and should, be over-ridden by the end-user in the `config/site.rb` file.
Sitepress.configure do |config|
  config.routes = false
  config.site = Sitepress::Site.new root_path: "."
end

# Create the module that should autoload without an issues.
require 'fileutils'
FileUtils.mkdir_p 'helpers'
File.write "helpers/foo_helper.rb", "module FooHelper; end;"

# Boot the Rails app
app = Sitepress::Server
app.initialize!

puts "Loading ::SiteController fails in Rails 7.0"
# See https://github.com/sitepress/sitepress/blob/rails-7/sitepress-rails/lib/sitepress/engine.rb#L15 for helper path configuration
# See https://github.com/sitepress/sitepress/blob/rails-7/sitepress-server/lib/sitepress/server.rb for the configuration of the Rails app this boots
p ::SiteController # This will raise an exception

Now for code that shows this WORKING under Rails 6:

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "sitepress", github: "sitepress/sitepress", branch: "rails-7"
  gem "rails"
end

require "sitepress/server"  # Load all the stuff needed setup the configuration below.

# Setup defaults for stand-alone Sitepress server in the current path. This
# can, and should, be over-ridden by the end-user in the `config/site.rb` file.
Sitepress.configure do |config|
  config.routes = false
  config.site = Sitepress::Site.new root_path: "."
end

# Create the module that should autoload without an issues.
require 'fileutils'
FileUtils.mkdir_p 'helpers'
File.write "helpers/foo_helper.rb", "module FooHelper; end;"

# Boot the Rails app
app = Sitepress::Server
app.initialize!

puts "Loading ::SiteController succeeds in Rails 6.x"
p ::SiteController # This will not raise an exception

Finally, in a third example under Rails 7.0, I demonstrate that this is WORKING when I attempt to load the constant a second time:

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "sitepress", github: "sitepress/sitepress", branch: "rails-7"
  gem "rails", github: "rails/rails", branch: "main"
end

# require "sitepress/boot"
require "sitepress/server"  # Load all the stuff needed setup the configuration below.

# Setup defaults for stand-alone Sitepress server in the current path. This
# can, and should, be over-ridden by the end-user in the `config/site.rb` file.
Sitepress.configure do |config|
  config.routes = false
  config.site = Sitepress::Site.new root_path: "."
end

# Create the module that should autoload without an issues.
require 'fileutils'
FileUtils.mkdir_p 'helpers'
File.write "helpers/foo_helper.rb", "module FooHelper; end;"

# Boot the Rails app
app = Sitepress::Server
app.initialize!

puts "Loading ::SiteController fails in Rails 7.0 on the first attempt"
begin
  p ::SiteController
rescue => e
  puts "Failed with #{e.inspect}"
end

puts "Loading ::SiteController succeeds in Rails 7.0 on the second attempt"
p ::SiteController

The following source files may be helpful to help diagnose the issue:

Expected behavior

I expect the FooHelper to be resolved in Rails 7.x, as it does in Rails 6.x. Here's what a succesful script run looks like from above:

SiteController

Actual behavior

The FooHelper module is not resolved when Rails attempts to find it. Here's what the error looks like from the first Rails 7.x script above:

/Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/activesupport/lib/active_support/inflector/methods.rb:280:in `constantize': uninitialized constant FooHelper (NameError)
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/activesupport/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/actionpack/lib/abstract_controller/helpers.rb:177:in `block in modules_for_helpers'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/actionpack/lib/abstract_controller/helpers.rb:170:in `map!'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/actionpack/lib/abstract_controller/helpers.rb:170:in `modules_for_helpers'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/actionpack/lib/action_controller/metal/helpers.rb:104:in `modules_for_helpers'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/actionpack/lib/abstract_controller/helpers.rb:148:in `helper'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/rails-a692e63bf400/actionpack/lib/action_controller/railties/helpers.rb:19:in `inherited'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/sitepress-cd078ab7255c/sitepress-server/rails/app/controllers/application_controller.rb:1:in `<top (required)>'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/zeitwerk-2.5.0.beta3/lib/zeitwerk/kernel.rb:27:in `require'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/zeitwerk-2.5.0.beta3/lib/zeitwerk/kernel.rb:27:in `require'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/bundler/gems/sitepress-cd078ab7255c/sitepress-server/rails/app/controllers/site_controller.rb:1:in `<top (required)>'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/zeitwerk-2.5.0.beta3/lib/zeitwerk/kernel.rb:27:in `require'
	from /Users/bradgessler/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/zeitwerk-2.5.0.beta3/lib/zeitwerk/kernel.rb:27:in `require'
	from bug.rb:40:in `<main>'

System configuration

Rails version: 7.x

Ruby version: 3.x

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions