Skip to content

Commit ebfca90

Browse files
committed
Do not memoize auto/eager load paths in engines
1 parent 0ed3c2a commit ebfca90

File tree

3 files changed

+74
-11
lines changed

3 files changed

+74
-11
lines changed

railties/lib/rails/engine.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ def load_seed
578578
end
579579

580580
initializer :set_eager_load_paths, before: :bootstrap_hook do
581-
ActiveSupport::Dependencies._eager_load_paths.merge(config.eager_load_paths)
581+
ActiveSupport::Dependencies._eager_load_paths.merge(config.all_eager_load_paths)
582582
config.eager_load_paths.freeze
583583
end
584584

@@ -705,14 +705,14 @@ def default_middleware_stack
705705
end
706706

707707
def _all_autoload_once_paths
708-
config.autoload_once_paths.uniq
708+
config.all_autoload_once_paths.uniq
709709
end
710710

711711
def _all_autoload_paths
712712
@_all_autoload_paths ||= begin
713-
autoload_paths = config.autoload_paths
714-
autoload_paths += config.eager_load_paths
715-
autoload_paths -= config.autoload_once_paths
713+
autoload_paths = config.all_autoload_paths
714+
autoload_paths += config.all_eager_load_paths
715+
autoload_paths -= config.all_autoload_once_paths
716716
autoload_paths.uniq
717717
end
718718
end

railties/lib/rails/engine/configuration.rb

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,45 @@ class Configuration < ::Rails::Railtie::Configuration
99
attr_accessor :middleware, :javascript_path
1010
attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
1111

12+
# An array of custom autoload paths to be added to the ones defined
13+
# automatically by Rails. These won't be eager loaded, unless you push
14+
# them to +eager_load_paths+ too, which is recommended.
15+
#
16+
# This collection is empty by default, it accepts strings and +Pathname+
17+
# objects.
18+
#
19+
# If you'd like to add +lib+ to it, please see +autoload_lib+.
20+
attr_reader :autoload_paths
21+
22+
# An array of custom autoload once paths. These won't be eager loaded
23+
# unless you push them to +eager_load_paths+ too, which is recommended.
24+
#
25+
# This collection is empty by default, it accepts strings and +Pathname+
26+
# objects.
27+
#
28+
# If you'd like to add +lib+ to it, please see +autoload_lib_once+.
29+
attr_reader :autoload_once_paths
30+
31+
# An array of custom eager load paths to be added to the ones defined
32+
# automatically by Rails. Anything in this collection is considered to be
33+
# an autoload path regardless of whether it was added to +autoload_paths+.
34+
#
35+
# This collection is empty by default, it accepts strings and +Pathname+
36+
# objects.
37+
#
38+
# If you'd like to add +lib+ to it, please see +autoload_lib+.
39+
attr_reader :eager_load_paths
40+
1241
def initialize(root = nil)
1342
super()
1443
@root = root
1544
@generators = app_generators.dup
1645
@middleware = Rails::Configuration::MiddlewareStackProxy.new
1746
@javascript_path = "javascript"
47+
48+
@autoload_paths = []
49+
@autoload_once_paths = []
50+
@eager_load_paths = []
1851
end
1952

2053
# Holds generators configuration:
@@ -81,16 +114,22 @@ def root=(value)
81114
@root = paths.path = Pathname.new(value).expand_path
82115
end
83116

84-
def eager_load_paths
85-
@eager_load_paths ||= paths.eager_load
117+
# Private method that adds custom autoload paths to the ones defined by
118+
# +paths+.
119+
def all_autoload_paths # :nodoc:
120+
autoload_paths + paths.autoload_paths
86121
end
87122

88-
def autoload_once_paths
89-
@autoload_once_paths ||= paths.autoload_once
123+
# Private method that adds custom autoload once paths to the ones defined
124+
# by +paths+.
125+
def all_autoload_once_paths # :nodoc:
126+
autoload_once_paths + paths.autoload_once
90127
end
91128

92-
def autoload_paths
93-
@autoload_paths ||= paths.autoload_paths
129+
# Private method that adds custom eager load paths to the ones defined by
130+
# +paths+.
131+
def all_eager_load_paths # :nodoc:
132+
eager_load_paths + paths.eager_load
94133
end
95134
end
96135
end

railties/test/application/configuration_test.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,30 @@ def assert_utf8
662662
assert_utf8
663663
end
664664

665+
# Regression test for https://github.com/rails/rails/issues/49629.
666+
test "config.paths can be mutated after accessing auto/eager load paths" do
667+
app_dir "vendor/auto"
668+
app_dir "vendor/once"
669+
app_dir "vendor/eager"
670+
671+
add_to_config <<~RUBY
672+
# Reading the collections is enough, no need to modify them.
673+
config.autoload_paths
674+
config.autoload_once_paths
675+
config.eager_load_paths
676+
677+
config.paths.add("vendor/auto", autoload: true)
678+
config.paths.add("vendor/once", autoload_once: true)
679+
config.paths.add("vendor/eager", eager_load: true)
680+
RUBY
681+
682+
app "development"
683+
684+
assert_includes ActiveSupport::Dependencies.autoload_paths, "#{Rails.root}/vendor/auto"
685+
assert_includes ActiveSupport::Dependencies.autoload_once_paths, "#{Rails.root}/vendor/once"
686+
assert_includes ActiveSupport::Dependencies._eager_load_paths, "#{Rails.root}/vendor/eager"
687+
end
688+
665689
test "config.paths.public sets Rails.public_path" do
666690
add_to_config <<-RUBY
667691
config.paths["public"] = "somewhere"

0 commit comments

Comments
 (0)