Autosave will double save records for some cyclic associations.
For example a child record with a parent association.
If save is called on the child before the parent has been saved,
the child will be saved twice.
The double save of the child will clear the mutation tracker on
the child record resulting in an incorrect dirty state.
```
# pirate has_one ship
ship = Ship.new(name: "Nights Dirty Lightning")
pirate = ship.build_pirate(catchphrase: "Aye")
ship.save!
ship.previous_changes # => returns {} but this should contain the changes.
```
When saving ship the following happens:
1. the `before_save` callbacks of the ship are called
2. the callbacks call `autosave_associated_records_for_pirate`
3. `autosave_associated_records_for_pirate` saves the pirate
4. the `after_save` callbacks of the pirate are called
5. the callbacks call `autosave_associated_records_for_ship`
6. `autosave_associated_records_for_ship` saves the ship
7. the ship is saved again by the original save
`autosave_associated_records_for_ship` saves the ship because the ship
association is set by inverse_of in a `has_one` on the pirate. This does
not happen with a `has_many` by default because the inverse is not set.
If setting the inverse on the `has_many` the problem occurs as well.
----------------------------
This commit adds a @saving state which tracks if a record is currently being saved.
If @saving is set to true, the record won't be saved by the autosave callbacks.
With this commit the following happens when saving a ship:
1. @saving is set to true
2. the `before_save` callbacks of the ship are called
3. the callbacks call `autosave_associated_records_for_pirate`
5. `autosave_associated_records_for_pirate` saves the pirate
6. the `after_save` callbacks of the pirate are called
6. `autosave_associated_records_for_ship` skip saving the ship
8. the ship is saved.
9. @saving is set to false
One disadvantage of this approach is the following...
While the child is no longer saved in the autosave, similar children
could be autosaved. This will result in unexpected order when creating
new records, as similar children will be commited first.
If an association scope would generate the same query but have different
values for `extending`, `skip_query_cache` or `strict_loading` we should
consider them the same for the purpose of generating the preload
batches.
I've found the test doesn't catch a future regression since it doesn't
assert the result of the preload.
Also, add extra assertions to assert the difference of the value type.
This reverts commit 8da6ba9cae21beae1ee3c379db7b7113d2731c9b.
The type is not standard to make sure preload work when the types don't
match.
See #14855.
OrderedHash is deprecated but there are some requires and references
to OrderedHash, which might be confusing.
As described in
https://github.com/rails/rails/issues/22681#issuecomment-166059717
OrderedHash is internal only so references in the docs should be
removed.
After assigning string "infinity" to datetime attribute with postgresql adapter, reading it back gets Float::INFINITY.
But assigning Float::INFINITY to datetime attribute results in getting nil value when ActiveRecord::Base.time_zone_aware_attributes is true.
This is due to TimeZoneConverter not handling Float::INFINITY appropriately.
This reverts commit d2f4541f126001e029078cc48a3a481e23ae3ed9.
It should work without curly braces.
See also: #41198, #41206, 81d90d81d0ee1fc1a649ab705119a71f2d04c8a2.
Keyword argument warnings are caused by #41206 to allow both
`current_page?(url_hash)` and `current_page?(**url_hash)` on Ruby 3.0.
Unfortunately it is super hard to support that for both Ruby 2.7 and 3.0
with the same method signature.
Closes#41710.
Since Ruby 2.7 `self.some_private_method` works fine.
So now that Ruby 2.7 is the minimal supported version,
`define_proxy_call` can always prepend `self.`
When requiring only "active_support/hash_with_indifferent_access",
calling `slice!` method on `HashWithIndifferentAccess` object
causes `NoMethodError`.
This is caused by `slice!` method calls `super` which is defined
in "active_support/core_ext/hash/slice" that' not required by this file.
Adding `require "active_support/core_ext/hash/slice"` to hwia
resolves this issue.
Note: since all tests `require_relative "abstract_unit"` that requires
"active_support/core_ext/hash/slice" eventually, it's pretty hard to
test method behavior without require.
Prior to this change, javascript_include_tag was sending a hint using
rel="preload" for all scripts, including those of type="module".
This causes the browser to make a request to preload the script, but
because the rel is incorrect, it won't be able to reuse it.
When passing type="module", it should use rel=modulepreload instead.
[0] developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
[1] developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link
[2] developer.mozilla.org/en-US/docs/Web/HTML/Link_types/modulepreload
While working on another branch I noticed that this `resource_id` was
set to a string. I ran all the tests for sqlite, mysql, and postgres and
none failed so I think this is an oversight. As far as I can tell this
was supposed to be an integer.
Setting up the parallel workers could be an overhead when running
individual files.
This patch disables that process in case the number of files to run
is less than one.
Results running a sample file:
Before:
```
actionpack $ bin/test test/controller/parameters/accessors_test.rb
Run options: --seed 48261
........................................................................
Finished in 0.211923s, 339.7460 runs/s, 552.0873 assertions/s.
72 runs, 117 assertions, 0 failures, 0 errors, 0 skips
```
After
```
actionpack $ bin/test test/controller/parameters/accessors_test.rb
Run options: --seed 5461
........................................................................
Finished in 0.008411s, 8560.2189 runs/s, 13910.3557 assertions/s.
72 runs, 117 assertions, 0 failures, 0 errors, 0 skips
```