From 0a8f4980f2e560562e925d28852a72dcf31898b2 Mon Sep 17 00:00:00 2001 From: Murad Iusufov Date: Tue, 1 Oct 2024 16:52:25 +0100 Subject: [PATCH] feat: use `with_connection` where possible https://github.com/rails/rails/pull/51349 - this allows rails 7.2 applications to raise an error or emit a deprecation warning whenever `ActiveRecord::Base.connection` is used. this makes sure that in rails 7.1 and after we use the new, preferred method. --- lib/counter_culture/counter.rb | 14 +++++++---- lib/counter_culture/reconciler.rb | 6 ++++- lib/counter_culture/with_connection.rb | 33 ++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 lib/counter_culture/with_connection.rb diff --git a/lib/counter_culture/counter.rb b/lib/counter_culture/counter.rb index 759a58b..77043de 100644 --- a/lib/counter_culture/counter.rb +++ b/lib/counter_culture/counter.rb @@ -1,3 +1,5 @@ +require_relative './with_connection' + module CounterCulture class Counter CONFIG_OPTIONS = [ :column_names, :counter_cache_name, :delta_column, :foreign_key_values, :touch, :delta_magnitude, :execute_after_commit ] @@ -65,11 +67,13 @@ def change_counter_cache(obj, options) # MySQL throws an ambiguous column error if any joins are present and we don't include the # table name. We isolate this change to MySQL because sqlite has the opposite behavior and # throws an exception if the table name is present after UPDATE. - quoted_column = if klass.connection.adapter_name == 'Mysql2' - "#{klass.quoted_table_name}.#{model.connection.quote_column_name(change_counter_column)}" - else - "#{model.connection.quote_column_name(change_counter_column)}" - end + quoted_column = WithConnection.new(klass).call do |connection| + if connection.adapter_name == 'Mysql2' + "#{klass.quoted_table_name}.#{connection.quote_column_name(change_counter_column)}" + else + "#{connection.quote_column_name(change_counter_column)}" + end + end column_type = klass.type_for_attribute(change_counter_column).type diff --git a/lib/counter_culture/reconciler.rb b/lib/counter_culture/reconciler.rb index bfec169..e5381a6 100644 --- a/lib/counter_culture/reconciler.rb +++ b/lib/counter_culture/reconciler.rb @@ -1,6 +1,8 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/module/attribute_accessors' +require_relative './with_connection' + module CounterCulture class Reconciler ACTIVE_RECORD_VERSION = Gem.loaded_specs["activerecord"].version @@ -312,7 +314,9 @@ def join_clauses(where) # using Postgres with schema-namespaced tables. But then it's required, # and otherwise it's just a no-op, so why not do it? def quote_table_name(table_name) - relation_class.connection.quote_table_name(table_name) + WithConnection.new(relation_class).call do |connection| + connection.quote_table_name(table_name) + end end def parameterize(string) diff --git a/lib/counter_culture/with_connection.rb b/lib/counter_culture/with_connection.rb new file mode 100644 index 0000000..0be30a2 --- /dev/null +++ b/lib/counter_culture/with_connection.rb @@ -0,0 +1,33 @@ +module CounterCulture + class WithConnection + def initialize(recipient) + @recipient = recipient + end + + attr_reader :recipient + + def call + if rails_7_2_or_greater? + recipient.with_connection do |connection| + yield connection + end + elsif rails_7_1? + recipient.connection_pool.with_connection do |connection| + yield connection + end + else + yield recipient.connection + end + end + + private + + def rails_7_1? + Gem::Requirement.new('~> 7.1.0').satisfied_by?(Gem::Version.new(Rails.version)) + end + + def rails_7_2_or_greater? + Gem::Requirement.new('>= 7.2.0').satisfied_by?(Gem::Version.new(Rails.version)) + end + end +end