Commit Graph

2702 Commits

Author SHA1 Message Date
Mike Dalessio 2bf7e25243
Raise a descriptive error when a store column is misconfigured
If a developer has neglected to use a structured column type (hstore
or json) or to declare a serializer with `ActiveRecord.store`:

```ruby
  class User < ActiveRecord::Base
    store_accessor :settings, :notifications
  end
```

then a `ConfigurationError` will now be raised with a descriptive
error message when the accessor is read or written:

```ruby
  puts user.notifications
  # ActiveRecord::ConfigurationError: the column 'settings' has not
  # been configured as a store.  Please make sure the column is
  # declared serializable via 'ActiveRecord.store' or, if your
  # database supports it, use a structured column type like hstore or
  # json.
```

Previously, in this situation, a `NoMethodError` was raised when the
accessor was read or written:

```ruby
  puts user.notifications
  # NoMethodError: undefined method `accessor' for an instance of ActiveRecord::Type::Text
```

Raising a descriptive exception should help developers understand more
quickly what's wrong and how to fix it.

Closes #51699
2024-05-23 15:59:56 -04:00
Joshua Young 0516eafda2 [Fix #51720] Infer association klass as top level if model has same demodularized name 2024-05-23 08:04:57 +09:00
eileencodes 227c590d02
Add test and fix changelog for `schema_cache_ignored_table?` 2024-05-21 15:37:38 -04:00
eileencodes e815c6663a
Make public method for `schema_cache_ignored_tables?`
Previously we only provided a method to set the ignored schema cache
tables, but there was no way to ask if a table was ignored by the schema
cache. Applications may want to implement their own schema cache, or at
least run this check. Rather than forcing them to implement an internal
method, this adds a way to ask whether a table is ignored by the schema
cache code.

Usage:

```ruby
ActiveRecord.schema_cache_ignored_tables = ["developers"]
ActiveRecord.schema_cache_ignored_tables?("developers")
```
2024-05-21 14:42:25 -04:00
Rafael Mendonça França 52b417bca6
This will be released in 7.2, not 8 2024-05-14 18:05:40 +00:00
fatkodima 94af7c181a Change `BatchEnumerator#destroy_all` to return the total number of affected rows 2024-05-13 22:54:25 +03:00
Rafael Mendonça França bf59d363fb
Clean CHANGELOG for 8.0 2024-05-13 16:55:52 +00:00
Rafael Mendonça França 37fd0e7fe4
Development of Rails 8.0 starts now
🎉
2024-05-13 16:45:20 +00:00
fatkodima e057037c72 Support `touch_all` in batches 2024-05-13 09:23:57 +09:00
Sampat Badhe a44fbb11a3
Correct typo in activerecord changelog [ci skip]
Correct typo in activerecord changelog for -https://github.com/rails/rails/pull/50662
2024-05-12 10:43:00 +05:30
fatkodima 47f25b268a Add support for `:if_not_exists` and `:force` options to `create_schema` 2024-05-11 16:40:20 +03:00
lulalala 0a36c36dd8 Add index_errors: :nested_attributes_order mode
which respects reject_if and is in nested_attributes order.

When in default index_errors:true mode,
fix #24390 and return index based on full association order.
2024-05-09 20:03:53 +08:00
Nikita Vasilevsky 9cadf61835
Warn about changing `query_constraints:` behavior
This commit adds a deprecation warning for the `query_constraints:`
association option. This option will change behavior in the future versions
of Rails and applications are encouraged to switch to `foreign_key:` to preserve the
current behavior.
2024-05-08 20:08:09 +00:00
David Heinemeier Hansson e8e077dd16
Add ENV["SKIP_TEST_DATABASE_TRUNCATE"] flag to speed up multi-process test runs (#51686) 2024-05-06 17:04:01 -07:00
nisusam e0b7136b3e Fix typo from Changelog [ci skip] 2024-05-02 17:23:21 +05:30
Claire fc26e44181 Add support for recursive CTE in Active Record
```ruby
Post.with_recursive(
  post_and_replies: [
    Post.where(id: 42),
    Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id'),
  ]
)
```

Generates the following SQL:

```sql
WITH RECURSIVE "post_and_replies" AS (
  (SELECT "posts".* FROM "posts" WHERE "posts"."id" = 42)
  UNION ALL
  (SELECT "posts".* FROM "posts" JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id)
)
SELECT "posts".* FROM "posts"
```
2024-05-02 12:32:27 +02:00
Cody Cutrer 5c5e8d2fd6 Pass validate(_check)_constraint through change_table 2024-05-01 15:33:37 -06:00
Joé Dupuis 2c88c80fc7
Add a Date decoder to the pg adapter to type cast dates
at the connection level

Fix #51448

Type cast columns of type `date` to ruby `Date` when running a raw
query through `ActiveRecord::Base.connection.select_all`.
2024-04-29 19:16:18 -07:00
Reid Lynch 715276071f
Strict loading using `:n_plus_one_only` does not eagerly load child associations.
Before:

    ```ruby
    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first
    # SELECT * FROM posts WHERE person_id = 1; -- non-deterministic order
    ```

    After:

    ```ruby
    person = Person.find(1)
    person.strict_loading!(mode: :n_plus_one_only)
    person.posts.first # this is 1+1, not N+1
    # SELECT * FROM posts WHERE person_id = 1 ORDER BY id LIMIT 1;
    ```

    Strict loading in `:n_plus_one_only` mode is designed to prevent performance issues when
    deeply traversing associations. It allows `Person.find(1).posts`, but _not_
    `Person.find(1).posts.map(&:category)`. With this change, child associations are no
    longer eagerly loaded, to match intended behavior and to prevent non-deterministic
    order issues caused by calling methods like `first` or `last`.
    Fixes #49473.
2024-04-19 00:05:13 +00:00
Rafael Mendonça França d60a23457c
Revert "Don't silently execute statements on migrations when they can't be reversed"
This reverts commit 5b04d448ab.

This is breaking more than it is fixing. We need to find a better way to
handle this.
2024-04-19 00:03:53 +00:00
Rafael Mendonça França 5b04d448ab
Don't silently execute statements on migrations when they can't be reversed
Fixes #51570.
2024-04-18 23:00:57 +00:00
Mike Dalessio fd1c635d2f Allow sqlite3 to float to version 2 2024-04-18 11:34:24 +02:00
fatkodima 82c02ef4d0 Allow `ActiveRecord::Base#pluck` to accept hash values 2024-04-13 21:39:36 +03:00
Petrik 79f0c6504d Fix small typo's in ActiveRecord Changelog [ci-skip] 2024-04-08 15:58:14 +02:00
Jean Boussier 3700aa90e3 Fix a typo in activerecord/CHANGELOG.md 2024-04-08 12:19:29 +02:00
Kevin McPhillips 869d802c48
Raise a descriptive error if the MySQL adapter fails to parse the version string. 2024-04-03 16:38:33 -04:00
Jean Boussier c2df237414 Allow to register transaction callbacks outside of a record
Ref: https://github.com/rails/rails/pull/26103
Ref: https://github.com/rails/rails/pull/51426

A fairly common mistake with Rails is to enqueue a job from inside a
transaction, and a record as argumemnt, which then lead to a RecordNotFound
error when picked up by the queue.

This is even one of the arguments advanced for job runners backed by the
database such as `solid_queue`, `delayed_job` or `good_job`. But relying
on this is undesirable iin my opinion as it makes the Active Job abstraction
leaky, and if in the future you need to migrate to another backend or even
just move the queue to a separate database, you may experience a lot of race
conditions of the sort.

But more generally, being able to defer work to after the current transaction
has been a missing feature of Active Record. Right now the only way to do it
is from a model callback, and this forces moving things in Active Record
models that sometimes are better done elsewhere. Even as a self-proclaimed
"service object skeptic", I often wanted this capability over the last decade,
and I'm sure it got asked or desired by many more people.

Also there's some 3rd party gems adding this capability using monkey patches.
It's not a reason to upstream the capability, but it's a proof that there is
demand for it.

Implementation wise, this proof of concept shows that it's not really hard to
implement, even with nested multi-db transactions support.

Co-Authored-By: Cristian Bica <cristian.bica@gmail.com>
2024-04-03 14:26:10 +02:00
fatkodima e79455f3d4 Add the ability to ignore counter cache columns while they are backfilling 2024-04-02 13:59:46 +03:00
Adrianna Chang eabcff22a8
Retry known idempotent SELECT queries on connection-related exceptions
This commit makes two types of queries retry-able by opting into our `allow_retry` flag:
1) SELECT queries we construct by walking the Arel tree via `#to_sql_and_binds`. We use a
new `retryable` attribute on collector classes, which defaults to true for most node types,
but will be set to false for non-idempotent node types (functions, SQL literals, etc). The
`retryable` value is returned from  `#to_sql_and_binds` and used by `#select_all` and
passed down the call stack, eventually reaching the adapter's `#internal_exec_query` method.

Internally-generated SQL literals are marked as retryable via a new `retryable` attribute on
`Arel::Nodes::SqlLiteral`.

2) `#find` and `#find_by` queries with known attributes. We set `allow_retry: true` in `#cached_find_by`,
and pass this down to `#find_by_sql` and `#_query_by_sql`.

These changes ensure that queries we know are safe to retry can be retried automatically.
2024-03-26 09:25:55 -04:00
Carlos Antonio da Silva 61a3e61e77 Minor text / error message tweaks, fixes, and punctuation
Improve a few sentences and add punctuation to some recent changelog &
guide entries.

[ci skip]
2024-03-25 10:21:08 -03:00
Nikita Vasilevsky 3df4d6927d Add CHANGELOG entries for association composite primary and foreign keys 2024-03-25 08:38:56 -04:00
Jean Boussier dd8fd52c07 Add `config.active_record.permanent_connection_checkout` setting
Controls whether `ActiveRecord::Base.connection` raises an error, emits a deprecation warning, or neither.

`ActiveRecord::Base.connection` checkouts a database connection from the pool and keep it leased until the end of
the request or job. This behavior can be undesirable in environments that use many more threads or fibers than there
is available connections.

This configuration can be used to track down and eliminate code that calls `ActiveRecord::Base.connection` and
migrate it to use `ActiveRecord::Base.with_connection` instead.

The default behavior remains unchanged, and there is currently no plans to change the default.
2024-03-21 12:19:15 +01:00
Carlos Antonio da Silva f404a949ce Fix AR changelog reference to new config [ci skip] 2024-03-18 13:09:43 -03: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 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 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 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
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 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
Rafael Mendonça França 240e9dac0a
Remove deprecated `#quote_bound_value` 2024-02-20 21:53:43 +00:00
Rafael Mendonça França 465fbd78f4
Remove deprecated `ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass` 2024-02-20 21:53:41 +00:00
Rafael Mendonça França 64cbcd7a8c
Remove deprecated support to apply some methods in the Connection Handle to the connections pools for the current role when the `role` arguments isn't provided 2024-02-20 21:53:38 +00:00
Rafael Mendonça França 9489c14b7b
Remove deprecated `#all_connection_pools` 2024-02-20 21:53:17 +00:00