1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix primary_abstract_class in lazy loaded envs

If you have an application that has `ApplicationRecord` and another
class like `PrimaryApplicationRecord` and the `PrimaryApplicationRecord`
is set to `primary_abstract_class`, then in a lazy loaded env like
development, it's possible for `application_record_class` to be set to
`ApplicationRecord`. This would then raise an error that you can't reset
the class if you then loaded `PrimaryApplicationRecord`.

To fix this we've removed the setter for `application_record_class` in
the fall through so that if this does happen, `ApplicationRecord` will
only be the primary class until the correct primary class is loaded.
If an application sets 2 classes to `primary_abstract_class`, the error
will still be raised.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com
This commit is contained in:
eileencodes 2021-05-17 11:59:37 -04:00
parent 61fb58f6a7
commit 00bad6102c
No known key found for this signature in database
GPG key ID: BA5C575120BBE8DF
2 changed files with 21 additions and 1 deletions

View file

@ -209,7 +209,6 @@ module ActiveRecord
self == Base.application_record_class
else
if defined?(ApplicationRecord) && self == ApplicationRecord
Base.application_record_class = self
true
end
end

View file

@ -79,6 +79,27 @@ class PrimaryClassTest < ActiveRecord::TestCase
Object.send(:remove_const, :ApplicationRecord)
end
def test_setting_primary_abstract_class_explicitly_wins_over_application_record_set_implicitly
Object.const_set(:ApplicationRecord, ApplicationRecord)
assert_predicate ApplicationRecord, :primary_class?
assert_predicate ApplicationRecord, :application_record_class?
assert_predicate ApplicationRecord, :abstract_class?
PrimaryClassTest::PrimaryAppRecord.primary_abstract_class
assert_predicate PrimaryClassTest::PrimaryAppRecord, :primary_class?
assert_predicate PrimaryClassTest::PrimaryAppRecord, :application_record_class?
assert_predicate PrimaryClassTest::PrimaryAppRecord, :abstract_class?
assert_not_predicate ApplicationRecord, :primary_class?
assert_not_predicate ApplicationRecord, :application_record_class?
assert_predicate ApplicationRecord, :abstract_class?
ensure
ActiveRecord::Base.application_record_class = nil
Object.send(:remove_const, :ApplicationRecord)
end
unless in_memory_db?
def test_application_record_shares_a_connection_with_active_record_by_default
Object.const_set(:ApplicationRecord, ApplicationRecord)