Summary
CanCan::ModelAdapters::ActiveRecord5Adapter#visit_nodes calls @model_class.send(:connection). Since Rails 7.2 the connection pool API has been redesigned: ActiveRecord::Base.connection is soft-deprecated in favour of ActiveRecord::Base.lease_connection (and with_connection), which better reflect that the caller is acquiring a connection from the pool rather than holding a permanent one (see rails/rails#51230).
connection still works on 7.2+, but apps that explicitly opt into the new connection-pool behaviour (or run with ActiveRecord.permanent_connection_checkout = :deprecated / :disallowed) will see warnings or errors from this call site. It also means cancancan does not benefit from the per-query lease/return behaviour that 7.2 introduced.
Reproduction
On Rails 7.2+:
ActiveRecord.permanent_connection_checkout = :deprecated
SomeModel.accessible_by(ability) # emits a deprecation warning
Affected file
lib/cancan/model_adapters/active_record_5_adapter.rb — #visit_nodes:
https://github.com/CanCanCommunity/cancancan/blob/develop/lib/cancan/model_adapters/active_record_5_adapter.rb#L48-L57
Proposed fix
Prefer lease_connection when available, fall back to connection for Rails < 7.2:
def visit_nodes(node)
if self.class.version_greater_or_equal?('5.2.0')
connection = @model_class.respond_to?(:lease_connection) ? @model_class.lease_connection : @model_class.connection
collector = Arel::Collectors::SubstituteBinds.new(connection, Arel::Collectors::SQLString.new)
connection.visitor.accept(node, collector).value
else
@model_class.send(:connection).visitor.compile(node)
end
end
This preserves support for Rails 5.2 / 6.x / 7.0 / 7.1 (which don't define lease_connection) while doing the right thing on 7.2+. The same respond_to?(:lease_connection) pattern is used by other gems that span the 7.2 boundary, e.g. good_job and pg_ha_migrations.
Happy to send a PR.
Summary
CanCan::ModelAdapters::ActiveRecord5Adapter#visit_nodescalls@model_class.send(:connection). Since Rails 7.2 the connection pool API has been redesigned:ActiveRecord::Base.connectionis soft-deprecated in favour ofActiveRecord::Base.lease_connection(andwith_connection), which better reflect that the caller is acquiring a connection from the pool rather than holding a permanent one (see rails/rails#51230).connectionstill works on 7.2+, but apps that explicitly opt into the new connection-pool behaviour (or run withActiveRecord.permanent_connection_checkout = :deprecated/:disallowed) will see warnings or errors from this call site. It also means cancancan does not benefit from the per-query lease/return behaviour that 7.2 introduced.Reproduction
On Rails 7.2+:
Affected file
lib/cancan/model_adapters/active_record_5_adapter.rb—#visit_nodes:https://github.com/CanCanCommunity/cancancan/blob/develop/lib/cancan/model_adapters/active_record_5_adapter.rb#L48-L57
Proposed fix
Prefer
lease_connectionwhen available, fall back toconnectionfor Rails < 7.2:This preserves support for Rails 5.2 / 6.x / 7.0 / 7.1 (which don't define
lease_connection) while doing the right thing on 7.2+. The samerespond_to?(:lease_connection)pattern is used by other gems that span the 7.2 boundary, e.g.good_jobandpg_ha_migrations.Happy to send a PR.