diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c0180d..a7c1969 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 0.5.0 (unreleased) +- Fixed connection leasing for Active Record 7.2+ - Dropped support for Ruby < 3.1 and Active Record < 7 ## 0.4.1 (2023-09-20) diff --git a/lib/active_median/model.rb b/lib/active_median/model.rb index 812dbf3..f74c401 100644 --- a/lib/active_median/model.rb +++ b/lib/active_median/model.rb @@ -1,16 +1,20 @@ module ActiveMedian module Model def median(column) - calculate_percentile(column, 0.5, "median") + connection_pool.with_connection do |connection| + calculate_percentile(column, 0.5, "median", connection) + end end def percentile(column, percentile) - calculate_percentile(column, percentile, "percentile") + connection_pool.with_connection do |connection| + calculate_percentile(column, percentile, "percentile", connection) + end end private - def calculate_percentile(column, percentile, operation) + def calculate_percentile(column, percentile, operation, connection) percentile = Float(percentile, exception: false) raise ArgumentError, "invalid percentile" if percentile.nil? raise ArgumentError, "percentile is not between 0 and 1" if percentile < 0 || percentile > 1 @@ -39,7 +43,7 @@ def calculate_percentile(column, percentile, operation) # column resolution node = relation.send(:arel_columns, [column]).first node = Arel::Nodes::SqlLiteral.new(node) if node.is_a?(String) - column = relation.connection.visitor.accept(node, Arel::Collectors::SQLString.new).value + column = connection.visitor.accept(node, Arel::Collectors::SQLString.new).value # prevent SQL injection percentile = connection.quote(percentile) diff --git a/test/median_test.rb b/test/median_test.rb index 207a2c9..c060c53 100644 --- a/test/median_test.rb +++ b/test/median_test.rb @@ -179,4 +179,15 @@ def test_hash def test_hash_block assert_equal 2.5, {a: 1, b: 1, c: 2, d: 3, e: 4, f: 100}.median { |k, v| v } end + + def test_connection_leasing + skip if mongoid? + + ActiveRecord::Base.connection_handler.clear_active_connections! + assert_nil ActiveRecord::Base.connection_pool.active_connection? + ActiveRecord::Base.connection_pool.with_connection do + User.median(:visits_count) + end + assert_nil ActiveRecord::Base.connection_pool.active_connection? + end end