mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Treat ActiveRecord::Base and ApplicationRecord as "primary"
When someone has a multi-db application their `ApplicationRecord` will look like: ```ruby class ApplicationRecord < ActiveRecord::Base self.abstract_class = true connects_to database: { writing: :primary, reading: :replica } end ``` This will cause us to open 2 connections to ActiveRecord::Base's database when we actually only want 1. This is because Rails sees `ApplicationRecord` and thinks it's a new connection, not the existing `ActiveRecord::Base` connection because the `connection_specification_name` is different. This PR changes `ApplicationRecord` classes to consider themselves the same as the "primary" connection. Fixes #36382
This commit is contained in:
parent
61c3ea8c04
commit
2f8b397258
3 changed files with 22 additions and 5 deletions
|
@ -173,7 +173,7 @@ module ActiveRecord
|
|||
raise "Anonymous class is not allowed." unless name
|
||||
|
||||
config_or_env ||= DEFAULT_ENV.call.to_sym
|
||||
pool_name = self == Base ? "primary" : name
|
||||
pool_name = primary_class? ? "primary" : name
|
||||
self.connection_specification_name = pool_name
|
||||
|
||||
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(Base.configurations)
|
||||
|
@ -204,11 +204,15 @@ module ActiveRecord
|
|||
# Return the specification name from the current class or its parent.
|
||||
def connection_specification_name
|
||||
if !defined?(@connection_specification_name) || @connection_specification_name.nil?
|
||||
return self == Base ? "primary" : superclass.connection_specification_name
|
||||
return primary_class? ? "primary" : superclass.connection_specification_name
|
||||
end
|
||||
@connection_specification_name
|
||||
end
|
||||
|
||||
def primary_class? # :nodoc:
|
||||
self == Base || defined?(ApplicationRecord) && self == ApplicationRecord
|
||||
end
|
||||
|
||||
# Returns the configuration of the associated connection as a hash:
|
||||
#
|
||||
# ActiveRecord::Base.connection_config
|
||||
|
|
|
@ -367,11 +367,24 @@ module ActiveRecord
|
|||
assert_same klass2.connection, ActiveRecord::Base.connection
|
||||
end
|
||||
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
end
|
||||
|
||||
class MyClass < ApplicationRecord
|
||||
end
|
||||
|
||||
def test_connection_specification_name_should_fallback_to_parent
|
||||
klassA = Class.new(Base)
|
||||
klassB = Class.new(klassA)
|
||||
klassC = Class.new(MyClass)
|
||||
|
||||
assert_equal klassB.connection_specification_name, klassA.connection_specification_name
|
||||
assert_equal klassC.connection_specification_name, klassA.connection_specification_name
|
||||
|
||||
assert_equal "primary", klassA.connection_specification_name
|
||||
assert_equal "primary", klassC.connection_specification_name
|
||||
|
||||
klassA.connection_specification_name = "readonly"
|
||||
assert_equal "readonly", klassB.connection_specification_name
|
||||
end
|
||||
|
|
|
@ -116,7 +116,7 @@ class LoadingTest < ActiveSupport::TestCase
|
|||
RUBY
|
||||
|
||||
app_file "app/models/post.rb", <<-MODEL
|
||||
class Post < ActiveRecord::Base
|
||||
class Post < ApplicationRecord
|
||||
end
|
||||
MODEL
|
||||
|
||||
|
@ -133,9 +133,9 @@ class LoadingTest < ActiveSupport::TestCase
|
|||
require "#{rails_root}/config/environment"
|
||||
setup_ar!
|
||||
|
||||
assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort
|
||||
assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata, ApplicationRecord].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort
|
||||
get "/load"
|
||||
assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata, Post].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort
|
||||
assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata, ApplicationRecord, Post].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort
|
||||
get "/unload"
|
||||
assert_equal [ActiveStorage::Blob, ActiveStorage::Attachment, ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata].collect(&:to_s).sort, ActiveRecord::Base.descendants.collect(&:to_s).sort
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue