mirror of https://github.com/rails/rails
Add deprecation and specific exceptions to warn when an adapter is using the legacy registration format in 7.2
This commit is contained in:
parent
9c22f35440
commit
79fb41ddd9
|
@ -31,6 +31,62 @@ module ActiveRecord
|
|||
class_name, path_to_adapter = @adapters[adapter_name.to_s]
|
||||
|
||||
unless class_name
|
||||
# To provide better error messages for adapters expecting the pre-7.2 adapter registration API, we attempt
|
||||
# to load the adapter file from the old location which was required by convention, and then raise an error
|
||||
# describing how to upgrade the adapter to the new API.
|
||||
legacy_adapter_path = "active_record/connection_adapters/#{adapter_name}_adapter"
|
||||
legacy_adapter_connection_method_name = "#{adapter_name}_connection".to_sym
|
||||
|
||||
begin
|
||||
require legacy_adapter_path
|
||||
# If we reach here it means we found the found a file that may be the legacy adapter and should raise.
|
||||
if ActiveRecord::ConnectionHandling.method_defined?(legacy_adapter_connection_method_name)
|
||||
# If we find the connection method then we care certain it is a legacy adapter.
|
||||
deprecation_message = <<~MSG.squish
|
||||
Database configuration specifies '#{adapter_name}' adapter but that adapter has not been registered.
|
||||
Rails 7.2 has changed the way Active Record database adapters are loaded. The adapter needs to be
|
||||
updated to register itself rather than being loaded by convention.
|
||||
Ensure that the adapter in the Gemfile is at the latest version. If it is, then the adapter may need to
|
||||
be modified.
|
||||
See:
|
||||
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-c-register
|
||||
MSG
|
||||
|
||||
exception_message = <<~MSG.squish
|
||||
Database configuration specifies '#{adapter_name}' adapter but that adapter has not been registered.
|
||||
Ensure that the adapter in the Gemfile is at the latest version. If it is, then the adapter may need to
|
||||
be modified.
|
||||
MSG
|
||||
else
|
||||
# If we do not find the connection method we are much less certain it is a legacy adapter. Even though the
|
||||
# file exists in the location defined by convenntion, it does not necessarily mean that file is supposed
|
||||
# to define the adapter the legacy way. So raise an error that explains both possibilities.
|
||||
deprecation_message = <<~MSG.squish
|
||||
Database configuration specifies nonexistent '#{adapter_name}' adapter.
|
||||
Available adapters are: #{@adapters.keys.sort.join(", ")}.
|
||||
Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary
|
||||
adapter gem to your Gemfile if it's not in the list of available adapters.
|
||||
Rails 7.2 has changed the way Active Record database adapters are loaded. Ensure that the adapter in
|
||||
the Gemfile is at the latest version. If it is up to date, the adapter may need to be modified.
|
||||
See:
|
||||
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters.html#method-c-register
|
||||
MSG
|
||||
|
||||
exception_message = <<~MSG.squish
|
||||
Database configuration specifies nonexistent '#{adapter_name}' adapter.
|
||||
Available adapters are: #{@adapters.keys.sort.join(", ")}.
|
||||
Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary
|
||||
adapter gem to your Gemfile and that it is at its latest version. If it is up to date, the adapter may
|
||||
need to be modified.
|
||||
MSG
|
||||
end
|
||||
|
||||
ActiveRecord.deprecator.warn(deprecation_message)
|
||||
raise AdapterNotFound, exception_message
|
||||
rescue LoadError => error
|
||||
# The adapter was not found in the legacy location so fall through to the error handling for a missing adapter.
|
||||
end
|
||||
|
||||
raise AdapterNotFound, <<~MSG.squish
|
||||
Database configuration specifies nonexistent '#{adapter_name}' adapter.
|
||||
Available adapters are: #{@adapters.keys.sort.join(", ")}.
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionHandling
|
||||
def fake_legacy_connection(config)
|
||||
ConnectionAdapters::FakeLegacyAdapter.new nil, logger
|
||||
end
|
||||
end
|
||||
|
||||
module ConnectionAdapters
|
||||
class FakeLegacyAdapter < AbstractAdapter
|
||||
def active?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
class FakeMisleadingLegacyAdapter < AbstractAdapter
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,34 +16,92 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
test "#register registers a new database adapter and #resolve can find it and raises if it cannot" do
|
||||
assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
exception = assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
ActiveRecord::ConnectionAdapters.resolve("fake")
|
||||
end
|
||||
|
||||
assert_match(
|
||||
/Database configuration specifies nonexistent 'fake' adapter. Available adapters are:/,
|
||||
exception.message
|
||||
)
|
||||
|
||||
ActiveRecord::ConnectionAdapters.register("fake", "FakeActiveRecordAdapter", @fake_adapter_path)
|
||||
|
||||
assert_equal "FakeActiveRecordAdapter", ActiveRecord::ConnectionAdapters.resolve("fake").name
|
||||
end
|
||||
|
||||
test "#register allows for symbol key" do
|
||||
assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
exception = assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
ActiveRecord::ConnectionAdapters.resolve("fake")
|
||||
end
|
||||
|
||||
assert_match(
|
||||
/Database configuration specifies nonexistent 'fake' adapter. Available adapters are:/,
|
||||
exception.message
|
||||
)
|
||||
|
||||
ActiveRecord::ConnectionAdapters.register(:fake, "FakeActiveRecordAdapter", @fake_adapter_path)
|
||||
|
||||
assert_equal "FakeActiveRecordAdapter", ActiveRecord::ConnectionAdapters.resolve("fake").name
|
||||
end
|
||||
|
||||
test "#resolve allows for symbol key" do
|
||||
assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
exception = assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
ActiveRecord::ConnectionAdapters.resolve("fake")
|
||||
end
|
||||
|
||||
assert_match(
|
||||
/Database configuration specifies nonexistent 'fake' adapter. Available adapters are:/,
|
||||
exception.message
|
||||
)
|
||||
|
||||
ActiveRecord::ConnectionAdapters.register("fake", "FakeActiveRecordAdapter", @fake_adapter_path)
|
||||
|
||||
assert_equal "FakeActiveRecordAdapter", ActiveRecord::ConnectionAdapters.resolve(:fake).name
|
||||
end
|
||||
end
|
||||
|
||||
class RegistrationIsolatedTest < ActiveRecord::TestCase
|
||||
include ActiveSupport::Testing::Isolation
|
||||
|
||||
def setup
|
||||
@original_adapters = ActiveRecord::ConnectionAdapters.instance_variable_get(:@adapters).dup
|
||||
end
|
||||
|
||||
test "#resolve raises if the adapter is using the pre 7.2 adapter registration API" do
|
||||
exception = assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
assert_deprecated(ActiveRecord.deprecator) do
|
||||
ActiveRecord::ConnectionAdapters.resolve("fake_legacy")
|
||||
end
|
||||
end
|
||||
|
||||
assert_match(
|
||||
/Database configuration specifies 'fake_legacy' adapter but that adapter has not been registered. Ensure that the adapter in the Gemfile is at the latest version. If it is, then the adapter may need to be modified./,
|
||||
exception.message
|
||||
)
|
||||
ensure
|
||||
ActiveRecord::ConnectionAdapters.instance_variable_get(:@adapters).delete("fake_legacy")
|
||||
end
|
||||
|
||||
test "#resolve raises if the adapter maybe is using the pre 7.2 adapter registration API but we are not sure" do
|
||||
exception = assert_raises(ActiveRecord::AdapterNotFound) do
|
||||
assert_deprecated(ActiveRecord.deprecator) do
|
||||
ActiveRecord::ConnectionAdapters.resolve("fake_misleading_legacy")
|
||||
end
|
||||
end
|
||||
|
||||
assert_match(
|
||||
/Database configuration specifies nonexistent 'fake_misleading_legacy' adapter. Available adapters are:/,
|
||||
exception.message
|
||||
)
|
||||
|
||||
assert_match(
|
||||
/Ensure that the adapter is spelled correctly in config\/database.yml and that you've added the necessary adapter gem to your Gemfile and that it is at its latest version. If it is up to date, the adapter may need to be modified./,
|
||||
exception.message
|
||||
)
|
||||
ensure
|
||||
ActiveRecord::ConnectionAdapters.instance_variable_get(:@adapters).delete("fake_misleading_legacy")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue