Use ActiveRecord::Base .with_connection rather than .connection#8474
Use ActiveRecord::Base .with_connection rather than .connection#8474davidrunger wants to merge 9 commits into
Conversation
Per comment [here][1], calling `ActiveRecord::Base.connection` is soft-deprecated, so this change uses `with_connection`, instead. [1]: https://github.com/rails/rails/blob/v7.2.1/activerecord/lib/active_record/connection_handling.rb#L259
|
See relevant Rails PR rails/rails#51349, where an I tried setting that config to |
|
Thanks for this PR, is there any deprecation warning in the logs that we missed? I was expecting to see a deprecation warning somewhere here: https://github.com/activeadmin/activeadmin/actions/runs/10706856019/job/29685533496 |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #8474 +/- ##
=======================================
Coverage 99.11% 99.11%
=======================================
Files 141 141
Lines 4069 4072 +3
=======================================
+ Hits 4033 4036 +3
Misses 36 36 ☔ View full report in Codecov by Sentry. |
@tagliala : No, there is no deprecation warning in the logs that you have missed. I guess that deprecation warnings would show up somewhere in the logs, if the ActiveAdmin test/sample app were to opt in to the deprecation warnings by adding |
|
@davidrunger ah sorry, I did not pay enough attention and I was confused by this line including |
Actually, unfortunately, I think that this is not true. Due to ... something -- sorry, I am not clear on the details ... I guess something having to do with tests being wrapped within a test-specific database transaction for transactional fixtures, which seems to affect the way that ActiveRecord connections get checked out from the connection pool ... unfortunately, even if we do set So, in summary, unfortunately, I'm not sure that it's really reasonably possible to have specs cover this change / be sensitive to this soft deprecation. In my own app, I actually ended up monkeypatching in tests the |
Order test use connection to quote order clause. Let's run one of the test outside fixture transaction to make sure that we call the proper method to get a connection. Context: rails/rails#51349 soft-deprecate calling `ActiveRecord::Base.connection` is favor of calling `ActiveRecord::Base.with_connection`. Setting `config.active_record.permanent_connection_checkout = :disallow` won't have effect in tests because we set `use_transactional_fixtures=true` which lease a connection before run all the test suite (https://github.com/rails/rails/blob/e1d58cfd05ae1cc0bfc1006b7ce973a7730831df/activerecord/lib/active_record/test_fixtures.rb#L172)
|
@davidrunger thanks for opening the PR! This is really interesting. I investigated a little bit. Tests ignores I don't think we can turn off With all this, I opened a PR ( https://github.com/davidrunger/activeadmin/pull/4) with my suggestions to add some specs about this change. Please let me know what you think. |
Use with connection specs
|
@mgrunberg Thank you so much for digging into this, for uncovering more clearly why the I was not familiar with the That being said, unfortunately, due to effectively needing to explicitly "opt in" to enforcing the Still, despite that potential downside, I do like having test coverage for this change, which is why I was happy to merge your PR into mine, even if it will not be globally effective, and even if it risks being somewhat misleading. |
To try to lessen this risk, I added 2f77680, which adds a comment in |
mgrunberg
left a comment
There was a problem hiding this comment.
That being said, unfortunately, due to effectively needing to explicitly "opt in" to enforcing the
config.active_record.permanent_connection_checkoutsetting in each relevant spec viauses_transaction, I guess that this still will not really provide ActiveAdmin with generalized/global protection against direct usage ofActiveRecord::Base.connection. I guess that other code could be added to ActiveAdmin that does useActiveRecord::Base.connection, and, unless that code is exercised in a test for which we have declareduses_transaction, then that usage will go undetected (i.e. it won't cause any specs to fail).
I agree with your assessment. My suggestion only works with existing code. New code may reintroduce the usage of the deprecated method.
In light of this, it perhaps could even be argued that adding
config.active_record.permanent_connection_checkout = :disallowedfor the Rails 7.2 test app is somewhat of a downside since perhaps it gives "a false sense of security", since (at first glance / naively) I think it probably suggests to most readers of that code that the Rails 7.2 ActiveAdmin test suite will respect that setting in general, whereas the reality is that the setting will only be enforced for specs that explicitly opt in to the protection viauses_transaction.
This is not entirely true. You are ignoring the fact that the template app is also used for development. Turning config.active_record.permanent_connection_checkout = :disallowed for Rails 7.2 template increases the chance of catching problems in new code by maintainers during development or manual tests of new branches.
Still, despite that potential downside, I do like having test coverage for this change, which is why I was happy to merge your PR into mine, even if it will not be globally effective, and even if it risks being somewhat misleading.
Thanks for merging my suggestions. My main goal was to add coverage of this change. Increasing the chances of catching the problem is nice to have. Indeed, it won't solve the problem globally but it's trade-off solution that works for now.
Let's not forget that we are dealing with a soft-deprecation. I imagine that when Rails turns this into a hard-derepcation we will get an error on any call to ActiveRecord::Base.connection despite the context.
I don't discard either the possibility that rubocop-rails adds a cop in the future to check the connection usage.
To try to lessen this risk, I added 2f77680, which adds a comment in spec/support/rails_template.rb about the need to opt into respecting that configuration setting in specs via uses_transaction.
Thanks for the extra comment. I found it helpful.
I made two suggestions about my original code comments. After re-reading them I found them cryptic.
Leaving that aside, the PR looks good to me.
@mgrunberg This is a really great point that I had not thought about. Thank you for mentioning it! It's great that adding On the other hand, this important point actually makes me realize that this PR should not currently be merged! ❗ , because the latest released version of For example, on the latest version of this branch, after freshly generating the development example app, if I log in to the example admin app, go to the categories index page, and search for categories with a name that contains "Rock"... ... then I get this exception: ... which is triggered by |
|
I have converted this PR to "draft" status, to indicate that it should not currently be merged, as I elaborated on in my comment just above. I don't have a ton of appetite for submitting a similar change to One option would be to not make that addition to the example application configuration, and instead just make the change here in Another option is to leave this PR as-is in draft mode, and wait/hope for someone to make a similar change to Or, rather than leaving this PR open in draft mode indefinitely, I'm also open to simply closing it, if that's what maintainers think is best / would prefer. But I guess that this is something that probably should be dealt with in ActiveAdmin sooner or later, as I imagine that more and more apps will probably start to enable this |
Co-authored-by: Matias Grunberg <[email protected]>
Co-authored-by: Matias Grunberg <[email protected]>
|
@davidrunger I see your point. I may have the time to work on a ransack PR with a similar change this week. Until then, I'm ok with leaving this as a draft. If I can't find the time to do that, or if it proves hard, another alternative is to find a way to set |
|
The deprecation is unlikely to happen anytime soon. We'll also have issues with other dependencies needing to update. We will reopen the PR if that area makes progress. Just let us know. Thank you. |
|
@javierjulio Can we reopen this? It is now deprecated, and if one is not using Puma but maybe Falcon as the web server then AA is broken as a deprecation is raised. |
|
@henrikbjorn any chance to replicate this? Maybe starting with https://github.com/activeadmin/demo.activeadmin.info, which is based on Ruby 3.4.7 and Rails 8.1.1 I don't know how to configure falcon |
|
@tagliala https://github.com/activeadmin/demo.activeadmin.info/compare/main...henrikbjorn:demo.activeadmin.info:connection-checkout-disallow?expand=1 It is when Try and load the admin users page and see the exception. |
|
@henrikbjorn excellent, thanks I was able to replicate with puma at http://localhost:3000/admin/comments with just that single line change diff --git a/config/application.rb b/config/application.rb
index 262d716..97caab5 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -35,5 +35,6 @@ module ActiveAdminDemo
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
+ config.active_record.permanent_connection_checkout = :disallowed
end
endSo I guess this is an existing issue, affecting both v3 and v4, starting from version 7.2 and above. It appears that I cannot reopen this PR, because the upstream is gone, let me check what we can do |


Per comment here, calling
ActiveRecord::Base.connectionis soft-deprecated, so this change useswith_connection, instead.