Explicitly order Railties by load order

Until now they were implicitly ordered by load order because of
`DescendantTracker#descendants` register them through the `inherited`
callback.

But now that on Ruby 3.1 we use the native `Class#descendants`,
the ordering is rather random, or at least can't be relied on.

So we add a counter and assign an index on every Railtie subclass
to be able to sort them explictly later.
This commit is contained in:
Jean Boussier 2021-11-25 11:36:56 +01:00
parent 4b6ac01fbb
commit 510d761f45
2 changed files with 40 additions and 4 deletions

View File

@ -146,7 +146,7 @@ module Rails
delegate :config, to: :instance
def subclasses
super.reject(&:abstract_railtie?)
super.reject(&:abstract_railtie?).sort
end
def rake_tasks(&blk)
@ -191,6 +191,23 @@ module Rails
instance.configure(&block)
end
def <=>(other) # :nodoc:
load_index <=> other.load_index
end
def inherited(subclass)
subclass.increment_load_index
super
end
protected
attr_reader :load_index
def increment_load_index
@@load_counter ||= 0
@load_index = (@@load_counter += 1)
end
private
def generate_railtie_name(string)
ActiveSupport::Inflector.underscore(string).tr("/", "_")

View File

@ -1312,9 +1312,28 @@ en:
get("/assets/bar.js")
assert_match "// App's bar js", last_response.body.strip
# ensure that railties are not added twice
railties = Rails.application.send(:ordered_railties).map(&:class)
assert_equal railties, railties.uniq
assert_equal <<~EXPECTED, Rails.application.send(:ordered_railties).flatten.map(&:class).map(&:name).join("\n") << "\n"
I18n::Railtie
ActiveSupport::Railtie
ActionDispatch::Railtie
ActiveModel::Railtie
ActionController::Railtie
ActiveRecord::Railtie
GlobalID::Railtie
ActiveJob::Railtie
ActionMailer::Railtie
Rails::TestUnitRailtie
Sprockets::Railtie
ActionView::Railtie
ActiveStorage::Engine
ActionCable::Engine
ActionMailbox::Engine
ActionText::Engine
Bukkits::Engine
Importmap::Engine
AppTemplate::Application
Blog::Engine
EXPECTED
end
test "railties_order adds :all with lowest priority if not given" do