提交 2f8b3972 编写于 作者: E eileencodes

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
上级 61c3ea8c
......@@ -173,7 +173,7 @@ def resolve_config_for_connection(config_or_env) # :nodoc:
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 @@ def connection
# 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 @@ def test_a_class_using_custom_pool_and_switching_back_to_primary
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 User < ActiveRecord::Base
RUBY
app_file "app/models/post.rb", <<-MODEL
class Post < ActiveRecord::Base
class Post < ApplicationRecord
end
MODEL
......@@ -133,9 +133,9 @@ class Post < ActiveRecord::Base
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册