Commit Graph

23501 Commits

Author SHA1 Message Date
Jean Boussier 89adf24a57
Merge pull request #51325 from gabriel-amaral/old-upsert-for-on-duplicate-raw-sql
Do not try to alias on key update when raw SQL is supplied
2024-03-14 16:26:00 +01:00
Gabriel Amaral ee483b68b3 Do not try to alias on key update when raw SQL is supplied 2024-03-14 13:20:00 +00:00
Jean Boussier 3771f7ea58 Stablize ConnectionPoolTests#test_idle_timeout_configuration
It flakes a lot on my machine because the timeouts are identical.
2024-03-14 09:54:43 +01:00
Rosa Gutierrez 4a0b2a0b5b Memoize `key_provider` from `key` or deterministic `key_provider` if any
The memoization of Scheme#key_provider was removed completely in
https://github.com/rails/rails/pull/51019 because it prevented
overriding the `key_provider` via `with_encryption_context`. However,
this also made our tests for the HEY app about 5 times slower. We traced
this down to all attributes where we either provide a key or declare them
as deterministic and have to derive a key to instantiate the provider
every time we load them. This might happen hundreds of times per test,
and ultimately, we call
```
ActiveSupport::KeyGenerator#generate_key
```
and
```
OpenSSL::KDF.pbkdf2_hmac
```
hundreds of times. This adds significant overhead per test.

In reality, what's overridden bv `with_encryption_context` is the value
used as default provider, that is, `ActiveRecord::Encryption.key_provider`.
This is only used in `Scheme#key_provider` if the scheme doesn't already have
either a `key_provider` passed directly, or a `key`, or is `deterministic`.
The `key_provider` passed directly is already memoized simply by having it
stored as is. Let's memoize the other two, in order, so we save all those
extra calls to derive the same keys again and again.
2024-03-13 22:41:10 +01:00
Sean Doyle c2ca7594dc `ActiveRecord::Migration.verbose` documentation [ci skip]
Follow-up to [#51258][]

Re-write `ActiveRecord::Migration.verbose` documentation to incorporate
[review feedback][] from [#51258][].

[#51258]: https://github.com/rails/rails/pull/51258
[review feedback]: https://github.com/rails/rails/pull/51258#discussion_r1519637097
2024-03-11 09:44:59 -04:00
Vipul A M bf96dcfa0d
Merge pull request #51258 from seanpdoyle/migration-verbose-class-attribute
Emphasize mention of `Migration.verbose` [ci skip]
2024-03-10 13:30:23 -04:00
Yasuo Honda 52353c8bf5 MySQL 8.0.19 introduces aliases in the VALUES and SET clauses of INSERT INTO ... ON DUPLICATE KEY UPDATE statement
This commit addresses the following errors against MySQL 8.0.18 or lower version of MySQL 8.0.

- Steps to reproduce

```ruby
git clone https://github.com/rails/rails
cd rails
git clone https://github.com/rails/buildkite-config .buildkite/
RUBY_IMAGE=ruby:3.3 docker-compose -f .buildkite/docker-compose.yml build base &&
  CI=1 MYSQL_IMAGE=mysql:8.0.18 docker-compose -f .buildkite/docker-compose.yml run mysqldb runner activerecord 'rake db:mysql:rebuild test:mysql2'
```

- Actual behavior

```ruby
... snip ...
Error:
InsertAllTest#test_upsert_all_implicitly_sets_timestamps_on_create_when_model_record_timestamps_is_false_but_overridden:
ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS `ships_values` ON DUPLICATE KEY UPDATE updated_at=(CASE WHEN (`ships`.`name`<' at line 1
    /usr/local/bundle/gems/mysql2-0.5.6/lib/mysql2/client.rb:151:in `_query'
    /usr/local/bundle/gems/mysql2-0.5.6/lib/mysql2/client.rb:151:in `block in query'
    /usr/local/bundle/gems/mysql2-0.5.6/lib/mysql2/client.rb:150:in `handle_interrupt'
    /usr/local/bundle/gems/mysql2-0.5.6/lib/mysql2/client.rb:150:in `query'
    lib/active_record/connection_adapters/mysql2/database_statements.rb:104:in `block (2 levels) in raw_execute'
    lib/active_record/connection_adapters/abstract_adapter.rb:997:in `block in with_raw_connection'
    /rails/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb:23:in `handle_interrupt'
    /rails/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb:23:in `block in synchronize'
    /rails/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb:19:in `handle_interrupt'
    /rails/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor.rb:19:in `synchronize'
    lib/active_record/connection_adapters/abstract_adapter.rb:969:in `with_raw_connection'
    lib/active_record/connection_adapters/mysql2/database_statements.rb:102:in `block in raw_execute'
    /rails/activesupport/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
    lib/active_record/connection_adapters/abstract_adapter.rb:1112:in `log'
    lib/active_record/connection_adapters/mysql2/database_statements.rb:101:in `raw_execute'
    lib/active_record/connection_adapters/abstract_mysql_adapter.rb:237:in `execute_and_free'
    lib/active_record/connection_adapters/mysql2/database_statements.rb:23:in `internal_exec_query'
    lib/active_record/connection_adapters/abstract/database_statements.rb:171:in `exec_insert_all'
    lib/active_record/connection_adapters/abstract/query_cache.rb:26:in `exec_insert_all'
    lib/active_record/insert_all.rb:55:in `execute'
    lib/active_record/insert_all.rb:13:in `block in execute'
    lib/active_record/connection_adapters/abstract/connection_pool.rb:384:in `with_connection'
    lib/active_record/connection_handling.rb:270:in `with_connection'
    lib/active_record/insert_all.rb:12:in `execute'
    lib/active_record/persistence.rb:363:in `upsert_all'
    test/cases/insert_all_test.rb:561:in `block in test_upsert_all_implicitly_sets_timestamps_on_create_when_model_record_timestamps_is_false_but_overridden'
    test/cases/insert_all_test.rb:809:in `with_record_timestamps'
    test/cases/insert_all_test.rb:560:in `test_upsert_all_implicitly_sets_timestamps_on_create_when_model_record_timestamps_is_false_but_overridden'

bin/rails test /rails/activerecord/test/cases/insert_all_test.rb:557

E
... snip ...
8856 runs, 25842 assertions, 1 failures, 52 errors, 41 skips
```

Follow up #51274

Refer to these release notes, WL and commits for MySQL 8.0.19 and 8.0.20.

- MySQL 8.0.19 supports aliases in the VALUES and SET clauses of INSERT INTO ... ON DUPLICATE KEY UPDATE statement
https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-19.html

> MySQL now supports aliases in the VALUES and SET clauses of INSERT INTO ... ON DUPLICATE KEY UPDATE statement
> for the row to be inserted and its columns. Consider a statement such as this one:

https://dev.mysql.com/worklog/task/?id=6312
c39355e9e6

- MySQL 8.0.20 deprecates the old `VALUES()` syntax in INSERT ... ON DUPLICATE KEY UPDATE statements

https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-20.html
> The use of VALUES() to access new row values in INSERT ... ON DUPLICATE KEY UPDATE statements
> is now deprecated, and is subject to removal in a future MySQL release.
> Instead, you should use aliases for the new row and its columns as implemented in MySQL 8.0.19 and later.

https://dev.mysql.com/worklog/task/?id=13325
6f3b9df50b
2024-03-09 00:03:39 +09:00
fatkodima 3c61c3d4f8 Fix flaky `upsert` test 2024-03-08 01:56:08 +02:00
fatkodima 0e7826e10e Fix `upsert` warning for MySQL 2024-03-07 15:35:14 +02:00
Sean Doyle 0faae8af77 Emphasize mention of `Migration.verbose` [ci skip]
The API documentation for `ActiveRecord::Migration` mentions controlling
the level of log output through a `.verbose` class attribute. The line
isn't wrapped in `<tt>`, `+`, or backticks, so isn't emphasized as if it
were code.

This commit visually emphasizes that line so that it's more obviously
code.
2024-03-06 17:12:55 -05:00
Carlos Antonio da Silva 2fa3294618
Merge pull request #51263 from buncis/update-delegate-type-doc
[ci skip] update delegated type doc to make it less confusing and in sync with rails guide
2024-03-06 13:22:44 -03:00
buncis 1c54153dc6
update docs to make it less confusing and in sync with rails guide 2024-03-06 20:31:34 +07:00
Yasuo Honda 3a7d96c485 Add missing :author_addresses in `OrderTest`
This commit addresses this CI failure https://buildkite.com/rails/rails-nightly/builds/247#018e0bea-7a88-45eb-94fa-be4155aeeeca/1164-1173

- Error without this commit
```ruby
$ bin/test test/cases/relation/order_test.rb test/cases/fixtures_test.rb -n "/^(?:OrderTest#(?:test_order_desc)|FixturesWithForeignKeyViolationsTest#(?:test_does_not_raise_if_no_fk_violations))$/" --seed 31115
Using sqlite3
Run options: -n "/^(?:OrderTest#(?:test_order_desc)|FixturesWithForeignKeyViolationsTest#(?:test_does_not_raise_if_no_fk_violations))$/" --seed 31115

.E

Error:
FixturesWithForeignKeyViolationsTest#test_does_not_raise_if_no_fk_violations:
RuntimeError: Foreign key violations found in your fixture data. Ensure you aren't referring to labels that don't exist on associations. Error from database:

Foreign key violations found: authors, authors, authors
    lib/active_record/fixtures.rb:704:in `rescue in check_all_foreign_keys_valid!'
    lib/active_record/fixtures.rb:701:in `check_all_foreign_keys_valid!'
    lib/active_record/fixtures.rb:688:in `block (2 levels) in insert'
    lib/active_record/connection_adapters/abstract/connection_pool.rb:384:in `with_connection'
    lib/active_record/fixtures.rb:685:in `block in insert'
    lib/active_record/fixtures.rb:676:in `each'
    lib/active_record/fixtures.rb:676:in `insert'
    lib/active_record/fixtures.rb:662:in `read_and_insert'
    lib/active_record/fixtures.rb:607:in `create_fixtures'
    test/cases/fixtures_test.rb:893:in `block (2 levels) in test_does_not_raise_if_no_fk_violations'
    /home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/testing/assertions.rb:49:in `assert_nothing_raised'
    test/cases/fixtures_test.rb:892:in `block in test_does_not_raise_if_no_fk_violations'
    test/cases/fixtures_test.rb:906:in `with_verify_foreign_keys_for_fixtures'
    test/cases/fixtures_test.rb:891:in `test_does_not_raise_if_no_fk_violations'

bin/test test/cases/fixtures_test.rb:884

Finished in 0.084771s, 23.5930 runs/s, 94.3720 assertions/s.
2 runs, 8 assertions, 0 failures, 1 errors, 0 skips
$
```

Refer to #43873 that has the same reason why it gets error.
2024-03-05 14:23:20 +09:00
Yasuo Honda a556be5ddc Use `ActiveRecord::Base.lease_connection` for uncached dirties tests
This commit addresses these errors since #51192 renames `.connection` into `.lease_connection`

Follow up #51204

```ruby
$ cd activerecord
$ bin/test test/cases/query_cache_test.rb -n /uncached_dirties/
Using sqlite3
Run options: -n /uncached_dirties/ --seed 57207

E

Error:
QueryCacheTest#test_query_cache_uncached_dirties:
NoMethodError: undefined method `connection' for class ActiveRecord::Base
    lib/active_record/dynamic_matchers.rb:22:in `method_missing'
    test/cases/query_cache_test.rb:712:in `block (2 levels) in test_query_cache_uncached_dirties'
    /home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/testing/assertions.rb:241:in `assert_no_changes'
    test/cases/query_cache_test.rb:712:in `block in test_query_cache_uncached_dirties'
    test/cases/query_cache_test.rb:771:in `block (2 levels) in middleware'
    /home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/execution_wrapper.rb:91:in `wrap'
    test/cases/query_cache_test.rb:771:in `block in middleware'
    test/cases/query_cache_test.rb:720:in `test_query_cache_uncached_dirties'

bin/test test/cases/query_cache_test.rb:709

E

Error:
QueryCacheTest#test_query_cache_connection_uncached_dirties:
NoMethodError: undefined method `connection' for class ActiveRecord::Base
    lib/active_record/dynamic_matchers.rb:22:in `method_missing'
    test/cases/query_cache_test.rb:726:in `block (2 levels) in test_query_cache_connection_uncached_dirties'
    /home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/testing/assertions.rb:241:in `assert_no_changes'
    test/cases/query_cache_test.rb:726:in `block in test_query_cache_connection_uncached_dirties'
    test/cases/query_cache_test.rb:771:in `block (2 levels) in middleware'
    /home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/execution_wrapper.rb:91:in `wrap'
    test/cases/query_cache_test.rb:771:in `block in middleware'
    test/cases/query_cache_test.rb:734:in `test_query_cache_connection_uncached_dirties'

bin/test test/cases/query_cache_test.rb:723

E

Error:
QueryCacheTest#test_query_cache_uncached_dirties_disabled_with_nested_cache:
NoMethodError: undefined method `connection' for class ActiveRecord::Base
    lib/active_record/dynamic_matchers.rb:22:in `method_missing'
    test/cases/query_cache_test.rb:740:in `block (2 levels) in test_query_cache_uncached_dirties_disabled_with_nested_cache'
    /home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/testing/assertions.rb:194:in `assert_changes'
    test/cases/query_cache_test.rb:740:in `block in test_query_cache_uncached_dirties_disabled_with_nested_cache'
    test/cases/query_cache_test.rb:771:in `block (2 levels) in middleware'
    /home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/execution_wrapper.rb:91:in `wrap'
    test/cases/query_cache_test.rb:771:in `block in middleware'
    test/cases/query_cache_test.rb:757:in `test_query_cache_uncached_dirties_disabled_with_nested_cache'

bin/test test/cases/query_cache_test.rb:737

Finished in 0.134429s, 22.3166 runs/s, 0.0000 assertions/s.
3 runs, 0 assertions, 0 failures, 3 errors, 0 skips
$
```
2024-03-03 23:37:54 +09:00
Donal McBreen 5d528ba0c8
Add dirties option to uncached (#51204)
This adds a `dirties` option to `ActiveRecord::Base.uncached` and
`ActiveRecord::ConnectionAdapters::ConnectionPool#uncached`.

Setting `dirties` to `false`, means database writes to the connection
pool will not mark any query caches as dirty.

The option defaults to `true` which retains the existing behaviour and
clears query caches on all connection pools used by the current thread.

Co-authored-by: Jeremy Daer <jeremy@rubyonrails.org>
2024-03-02 19:01:24 -08:00
Jean Boussier ec7deca7ee Refactor InsertAll not to permanently lease a connection
Extracted from: https://github.com/rails/rails/pull/50793
2024-03-01 15:33:45 +01:00
Jean Boussier 2bf0d68de6 Fix a typo in ConnectionPoool#connection deprecation (again) 2024-03-01 15:32:58 +01:00
Jean Boussier f657842090 Fix a typo in ConnectionPoool#connection deprecation 2024-03-01 15:28:00 +01:00
Jean Boussier 7263da542b Deprecate `ConnectionPool#connection`
Replaced by `#lease_connection` to better reflect what it does.

`ActiveRecord::Base#connection` is deprecated in the same way
but without a removal timeline nor a deprecation warning.

Inside the Active Record test suite, we do remove `Base.connection`
to ensure it's not used internally.

Some callsites have been converted to use `with_connection`,
some other have been more simply migrated to `lease_connection`
and will serve as a list of callsites to convert for
https://github.com/rails/rails/pull/50793
2024-03-01 14:32:55 +01:00
Jean Boussier 38e8609ded Make `.connection` always return a permanently leased connection
Ref: https://github.com/rails/rails/pull/51083

The introduction of `ActiveRecord::Base.with_connection` somewhat broke
some expectations, namely that calling `.connection` would cause the
connection to be permenently leased, hence that future calls to it
would return the same connection, with all it's possible environmental
changes.

So any call to `.connection`, even inside `.with_connection` should
cause the lease to be sticky, and persist beyond the `with_connection`
block.

Also rename `.connection` into `.lease_connection`, as to make it
more explicit.
2024-03-01 11:37:06 +01:00
Jean Boussier 1d0b396f40 Clear all threads query cache when a connection is pinned
Ref: https://github.com/Shopify/maintenance_tasks/pull/983#issuecomment-1969407080
Ref: https://github.com/rails/rails/pull/51151

Now that query caches are owned by the pool, and assigned on connections
during checkout, when running multithreaded code inside transactional
tests (typically system tests), the two threads uses the same connection
but not the same cache.

So it's important that we do clear the caches for all threads when
a connection is pinned.
2024-02-29 09:21:18 +01:00
Jean Boussier ef947f9932 Expose a generic fixture accessor for fixture names that may conflict with Minitest
```ruby
assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
```

This was brought to me by someone with a `Metadata` model. The fixtures
accessor being `metadata` which conflicts with the `metadata` method
recently added in `Minitest`.
2024-02-28 16:09:23 +01:00
Joshua Young f42d9cbc32 [Fix #51164] `Model.query_constraints` with single non-primary-key column raises incorrect error 2024-02-28 14:19:10 +10:00
Rafael Mendonça França 649e99bf92
Merge pull request #51206 from fatkodima/fix-indexes-for-nonexisting-table
Fix `indexes` method for non-existing MySQL tables
2024-02-27 16:29:49 -05:00
fatkodima 8510efa841 Fix `indexes` method for non-existing MySQL tables 2024-02-27 13:39:01 +02:00
Jean Boussier 0016280f4f Don't require an active connection for table and column quoting
Extracted from: https://github.com/rails/rails/pull/50793

Right now quoting table or column names requires a leased Adapter
instance, even though none of the implementations actually requires
an active connection.

The idea here is to move these methods to the class so that the quoting
can be done without leasing a connection or even needing the connection
to ever have been established.

I also checked `activerecord-sqlserver-adapter` and `oracle-enhanced`
gems, and neither need an active connection.
2024-02-27 11:19:00 +01:00
Carlos Antonio da Silva c402ec7872 Add punctuation on some newly added API docs [ci skip] 2024-02-26 13:32:39 -03:00
Jean Boussier 6e74098b8c Fix `Migrator.current_version` to instantiate `SchemaMigration` correctly
This was missed in https://github.com/rails/rails/pull/51162
2024-02-26 12:49:31 +01:00
Vipul A M 2abee307fe
Merge pull request #51184 from ConfusedVorlon/document_after_commit_deduplication
[ci skip] Add warning about deduplication of after_xxx_commit shortcuts
2024-02-25 16:30:11 -05:00
Lex Cao 48036fee0d Fix typo 2024-02-25 23:11:40 +08:00
Rob Jonson 79fa0e3b2d Add warning about deduplication of after_xxx_commit shortcuts 2024-02-24 19:40:13 +00:00
fatkodima 5db70c979e Fix flaky `multi_db_migrator_test.rb` test 2024-02-24 02:38:31 +02:00
Jean Boussier 2cbedfdb2e Refactor FixtureSet to deal with connection pools
Extracted from: https://github.com/rails/rails/pull/50793

Allow to check the cache without checking out a connection.
2024-02-23 11:25:33 +01:00
Jean Boussier 932e029ad7
ConnectionPool: handle schema_reflection being re-assigned
This fixes a regression recently introduced that a schema_reflection
assignment from taking effect.
2024-02-22 21:13:04 +00:00
Jean Boussier a918394974 Refactor InternalMetadata, MigrationContext to belong to the pool
Extracted from: https://github.com/rails/rails/pull/50793

Similar to the recent refactoring of schema caches, rather than to directly
hold a connection, they now hold a pool and checkout a connection when needed.
2024-02-22 12:46:41 +01:00
Rafael Mendonça França 939742d69e
Merge pull request #50901 from joshuay03/fix-autosave-has-one-setting-fk-when-unchanged
[Fix #50897] Autosaving `has_one` sets foreign key attribute when unchanged
2024-02-21 15:21:23 -05:00
Rafael Mendonça França 3e42d79c99
Merge pull request #51078 from saleh-alhaddad/support_join_types_in_where_associated
Fix override existing join types in the query in the `where.associated` method
2024-02-21 15:10:24 -05:00
saleh-alhaddad 3400aac7f9
Fix an issue in the `where.associated` method 2024-02-21 18:12:15 +00:00
mylesboone 278d6574cf
`ActiveRecord::Relation#order` supports hash like `ActiveRecord::Relation#where` (#50000)
* relation#order supports hash like relation#where

This allows for an ActiveRecord::Relation to take a hash such as
`Topic.includes(:posts).order(posts: { created_at: :desc })`

* use is_a? to support subclasses of each

Co-authored-by: Rafael Mendonça França <rafael@rubyonrails.org>
2024-02-21 12:43:15 -05:00
Jean Boussier 684131a4f0
Merge pull request #51139 from Shopify/relation-bound-sql-literal
Relation#where build BoundSqlLiteral rather than eagerly interpolate
2024-02-21 16:49:45 +01:00
Carlos Antonio da Silva baad391196 Remove unused intermediate variable
It was necessary to return properly with the previous deprecation code,
which was removed in eccc6061f4.
2024-02-21 09:31:27 -03:00
Jean Boussier 8e6a5deca6 Relation#where build BoundSqlLiteral rather than eagerly interpolate
Ref: https://github.com/rails/rails/pull/50793

To make not caching connection checkout viable, we need to reduced
the amount of places where we need a connection.

Once big source of this is query/relation building, where in many
cases it eagerly quote and interpolation bound values in SQL fragments.

Doing this requires an active connection because both MySQL and Postgres
may quote values differently based on the connection settings.

Instead of eagerly doing all this, we can instead just insert these
as bound values in the Arel AST. For adapters with prepared statements
this is better anyway as it will avoid leaking statements, and for those
that don't support it, it will simply delay the quoting to just
before the query is executed.

However, the `%` API (`where("title = %s", something)`) can't realistically
be fixed this way, but I don't see much value in it and it probably should
be deprecated and removed.
2024-02-21 13:22:55 +01:00
Jean Boussier 1af361b30b Don't forcefully clear temporarily disabled query caches
Followup: https://github.com/rails/rails/pull/50938

The behavior changed to always clear the query cache as soon
as it's disabled, on the assumption that once queries have been
performed without it, all bets are off.

However that isn't quite true, we can apply the same clearing
logic than when it's enabled. If you perform read only queries
without the cache, there is no reason to clear it.
2024-02-21 11:47:54 +01:00
Jean Boussier e88dba8f0b clear_query_caches_for_current_thread: avoid pinning all connections
Ref: https://github.com/rails/rails/pull/51083#discussion_r1496720821

Now that the pool is owned by the pool, we can clear it without
hacing to checkout a connection.
2024-02-21 10:26:28 +01:00
Joshua Young a518b5a9d9 [Fix #50897] Autosaving `has_one` sets foreign key attribute when unchanged 2024-02-21 18:07:44 +10:00
Rafael Mendonça França 842ca2137f
Merge pull request #51047 from johnpitchko/add-query-docs-to-delegated-type
Add query docs for delegated type [ci skip]
2024-02-20 18:22:49 -05:00
Rafael Mendonça França eccc6061f4
Remove deprecated behavior that would rollback a transaction block when exited using `return`, `break` or `throw`. 2024-02-20 21:56:51 +00:00
Rafael Mendonça França c313d91613
Remove deprecated support to pass `rewhere` to `ActiveRecord::Relation#merge` 2024-02-20 21:56:13 +00:00
Rafael Mendonça França c09956a3ad
Remove deprecated support to pass `deferrable: true` to `add_foreign_key` 2024-02-20 21:55:04 +00:00
Rafael Mendonça França 95b48d8a3b
Remove deprecated support to quote `ActiveSupport::Duration` 2024-02-20 21:54:57 +00:00