All validations are called on `#save` by default.
The Absence, Acceptance, Presence validators don't do anything special,
so there is no reason to mention they are called on `#save` by default.
Instead we can mention all validations are called in `#save` by default
in ActiveRecord::Validations.
Co-authored-by: Gannon McGibbon <gannon@hey.com>
Make it clearer that in the ActiveRecord AbsenceValidator, the
associated object is not _only_ absent if it is marked for destruction.
For the ActiveRecord PresenceValidator we can point to the ActiveModel
validations, like we do for other validations as well. This allows us to
remove some duplicated documentation.
After af7428c4ac the yarn install
instructions was dropped from bin/setup. This commmit adds it into
the setup script again if the user is not using importmap.
In https://github.com/rails/rails/pull/43036 an optimisation was applied
to ActiveModel#Serialization to speed up the generation of a
serialized_hash by avoiding loading the subjects attributes by using an
attribute_names method. A fallback method,
ActiveModel::Serialization#attribute_names` was added as #attribute_names
isn't part of the public API of ActiveModel.
Unfortunately, this fallback method happens to override the ActiveRecord
method (as ActiveModel::Serialization is a later mixin than
ActiveRecord::AttributeMethods), so this change didn't actually provide
an optimisation - the full attribute data was loaded as per [1]
This change also, in our case, produced some severe performance issues
as it introduced an N+1 query in a situation where we had one gem,
Globalize [2], which adds in dynamic attributes that are loaded by a query;
and another gem, Transitions [3], that checks attribute names at
initialization. The combination of these meant that for every model that
was initialized an extra query would run - no matter what includes or
eager_load steps were in place. This rapidly hindered our applications'
performance and meant we had to rollback the Rails 7 upgrade.
Following rafaelfranca's suggestion [4] this adds a
`attribute_names_for_serialization` method to Serialization modules in
ActiveRecord and ActiveModel. This allows the ActiveRecord one to
override the ActiveModel fallback and thus be optimised.
Some basic benchmarks of this follow - they use code from
https://github.com/ollietreend/rails-demo and have some pretty large
arrays set as serialized attributes [5] to demonstrate impacts.
Loading attribute names:
Rails 7.0.2.3
```
> Benchmark.ms { Widget.all.map(&:attribute_names) }
Widget Load (131.1ms) SELECT "widgets".* FROM "widgets"
=> 20108.852999983355
```
This patch
```
> Benchmark.ms { Widget.all.map(&:attribute_names) }
Widget Load (144.0ms) SELECT "widgets".* FROM "widgets"
=> 237.96699999365956
```
Using serializable_hash:
Rails 7.0.2.3
```
> widgets = Widget.all.to_a; Benchmark.ms { widgets.map { |w| w.serializable_hash(only: []) } }
Widget Load (133.3ms) SELECT "widgets".* FROM "widgets"
=> 22071.45000001765
```
This patch
```
> widgets = Widget.all.to_a; Benchmark.ms { widgets.map { |w| w.serializable_hash(only: []) } }
Widget Load (83.5ms) SELECT "widgets".* FROM "widgets"
=> 67.9039999959059
```
[1]: eeb2cfb686/activemodel/lib/active_model/serialization.rb (L151-L154)
[2]: https://github.com/globalize/globalize
[3]: https://github.com/troessner/transitions
[4]: https://github.com/rails/rails/pull/44770#pullrequestreview-922209612
[5]: 525f88887b/db/seeds.rb
* Remove outdated information
* Clean up language and sentence structure to be clearer
* Remove commands that are no longer necessary
* Add note about how to move past the native extension issues with
mysql2 since it's become a big problem.
Condition arguments are escaped to prevent SQL injection, SQL LIKE
wildcards (i.e., `%` and `_`) are not escaped. But there are no
description about SQL LIKE escape in the rails querying guide. So,
this adds a description about SQL LIKE escape to the guide.
- `#first` raises an error when called on a beginless range.
Using `#begin` to get the first element instead.
- Adding additional equality condition to cover the case when both
ranges are beginless
Allow `ActionController::Parameters.to_h` to receive a block to provide
parity with `Hash#to_h`. The provided block recieves `key, value` and
yields a two-element array/keypair which can be transformed in the
resulting Hash.
https://ruby-doc.org/core-2.7.5/Hash.html#method-i-to_h
When an `escape_character` is specified, `sanitize_sql_like` will escape
occurrences of it rather than `"\\"`.
This commit also modifies the examples to demonstrate that behavior.
This has been broken since the logging context was added in
6be9c498bc
Also added a higher level test to ensure that this isn't broken again in
the future.