| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
| | | | | | | |
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
The `@offsets` cache is used by FinderMethods to cache records found by
find_nth. This cache is cleared in AR::Relation#reset, but not in
CollectionProxy#reset or CollectionProxy#reload.
Because of this, since #29098, calling #first/#find_nth/etc after
calling #reload or #reset on an association could return a stale record.
This is an issue both when the full association target is loaded and
when the item is loaded in #find_nth.
This commit solves the problem by clearing the `@offsets` cache in
CollectionProxy#reset and CollectionProxy#reload.
|
|/ / / / / /
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Doing `Author.joins(:posts).merge(Post.joins(:comments))` does this
`SELECT ... INNER JOIN posts ON... LEFT OUTER JOIN comments ON...`
instead of doing
`SELECT ... INNER JOIN posts ON... INNER JOIN comments ON...`.
This behavior is unexpected and makes little sense as, basically, doing
`Post.joins(:comments)` means I want posts that have comments. Turning
it to a LEFT JOIN means I want posts and join the comments data, if
any.
We can see this problem directly in the existing tests.
The test_relation_merging_with_merged_joins_as_symbols only does joins
from posts to comments to ratings while the ratings fixture isn't
loaded, but the count is non-zero.
|
| |/ / / /
|/| | | |
| | | | |
| | | | | |
Because constructing `scope` is a little expensive.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
A collection association will raise on `#create_association` when the parent is
unpersisted. A singular association should do the same. This addresses
issue #29219.
|
| | | | | |
|
|\ \ \ \ \
| | | | | |
| | | | | |
| | | | | | |
Fix association with extension issues
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
As @matthewd's suggestion, if `klass` has no default scope, it will more
faster.
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Some third party modules expects that association returns same proxy
object each time (e.g. for stubbing collection methods:
https://github.com/rspec/rspec-rails/issues/1817).
So I decided that cache the proxy object and reset scope in the proxy
object each time.
Related context: https://github.com/rails/rails/commit/c86a32d7451c5d901620ac58630460915292f88b#commitcomment-2784312
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
This fixes the following issues.
* `association_scope` doesn't include `default_scope`. Should use `scope` instead.
* We can't use `method_missing` for customizing existing method.
* We can't use `relation_delegate_class` for sharing extensions. Should extend per association.
|
|/ / / / /
| | | | |
| | | | |
| | | | | |
Using `Association#interpolate` was removed since #11251.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Remove unused `JoinPart#name`
|
| |/ / / / |
|
|/ / / /
| | | |
| | | |
| | | |
| | | | |
The only difference between `make_inner_joins` and
`make_left_outer_joins` is the `join_type`.
|
| | | |
| | | |
| | | |
| | | | |
Since through association is always loaded by `preloader.preload`.
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
`ClassSpecificRelation` has `method_missing` and the `method_missing` is
called first. if an associated class has the missing method in a
relation, never reach to the `method_missing` in the `CollectionProxy`.
I extracted `DelegateExtending` and included it to the delegate class
that including `ClassSpecificRelation` to fix the issue.
Fixes https://github.com/rails/rails/pull/28246#issuecomment-296033784.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
association saved in the callback
Related #18155, #26661, 268a5bb, #27434, #27442, and #28599.
Originally #18155 was introduced for preventing double insertion caused
by the after save callback. But it was caused the before save issue
(#26661). 268a5bb fixed #26661, but it was caused the performance
regression (#27434). #27442 added new record to `target` before calling
callbacks for fixing #27434. But it was caused double firing before save
callback (#28599). We cannot add new object to `target` before saving
the object.
This is improving #18155 to only track callbacks after `save`.
Fixes #28599.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
Since #28473 `uniq` is delegated to `records`, so `CollectionProxy#uniq`
is unnecessary.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Extension methods should not delegate to `scope` to respect dirty
target on `CollectionProxy`.
Fixes #28419.
|
| | | |
| | | |
| | | |
| | | | |
Follow up of #28453.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Use it to specify that an association should be initialized with a
particular record before validation. For example:
# Before
belongs_to :account
before_validation -> { self.account ||= Current.account }
# After
belongs_to :account, default: -> { Current.account }
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The `select` in `QueryMethods` is also an enumerable method.
Enumerable methods with block should delegate to `records` on
`CollectionProxy`, not `scope`.
Fixes #28348.
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Reflections only use their own information to create a `join_keys`
object. This means that we can call `join_keys` on a reflection object
and have it be context-free.
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Scopes can only ever be *not* reflection objects when they are passed in
to the Reflection constructor. Given this fact, we can eliminate is_a
checks and an intermediate array object by just asking the reflection
object for join scopes.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
I don't think we actually need this parameter anymore. Nobody seems to
be using it.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
I incorrectly changed behavior of `dup`. Reading the original issue I
thought that `dup` should retain the original contents of the record
and it's associations but it is in fact supposed to be a copy as if a
record had been reinitialized.
This reverts commit ca8c21df0fdbf1f03ba2f7fb16b39c3282dc1be0.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
In Rails 3.2 dupping a `CollectionProxy` would dup it's `load_target` as
well. That functionality has been broken since the release of Rails 4.0.
I hit this in an application upgrade and wondered why duplicating a
CollectionProxy and assigning it to a variable stopped working.
When calling `dup` on a `CollectionProxy` only the owner (ex.
topic) was getting duplicated and the `load_target` would remain in tact
with it's original object ID. Dupping the `load_target` is useful for performing
a logging operation after records have been destroyed in a method.
For example:
```
def transfer_operation
saved_replies = topic.replies
topic.replies.clear
saved_replies.each do |reply|
user.update_replies_count!
end
end
```
This change adds a `initialize_dup` method that performs a `deep_dup` on
the `@associatiation` so that the `load_target` is dupped as well.
Fixes #17117
|
|\ \ \ \
| |/ / /
|/| | | |
Delegate to `scope` rather than `merge!` for collection proxy
|
| | | | |
|
| | | | |
|
| | | |
| | | |
| | | |
| | | | |
Because merging the association scope was removed.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
`merge! association.scope(nullify: false)` is expensive but most methods
do not need the merge.
|
| | | |
| | | |
| | | |
| | | | |
Fixes #27666.
|
|\ \ \ \
| | | | |
| | | | | |
Reload `through_record` that has been destroyed in `create_through_record`
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This is an alternative of #27714.
If `has_one :through` association has set `nil`, `through_record` is
destroyed but still remain loaded target in `through_proxy` until
`reload` or `reset` explicitly.
If `through_proxy` is not reset (remain destroyed (frozen) target),
setting new record causes `RuntimeError: Can't modify frozen hash`.
To prevent `RuntimeError`, should reload `through_record` that has been
destroyed in `create_through_record`.
|
|/ / / /
| | | |
| | | |
| | | | |
`PolymorphicReflection` needs to be custom for handling scope lambdas
|
| | | |
| | | |
| | | |
| | | | |
because Struct.new returns a Class, we just can give it a name and use it directly without inheriting from it
|
| | | |
| | | |
| | | |
| | | | |
(I personally prefer writing one string in one line no matter how long it is, though)
|
| | | |
| | | |
| | | |
| | | | |
Actually, private methods cannot be called with `self.`, so it's not just redundant, it's a bad habit in Ruby
|
|\ \ \ \
| | | | |
| | | | | |
Avoid to call `set_inverse_instance` twice for `has_many` association
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
`create`, `create!`, and `concat` in `has_many` association hits
`set_inverse_instance` twice. It is enough to hit only once.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Simply we can do `target.pluck(reflection.association_primary_key)` if
`target` is loaded.
|
| | | | | |
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This issue was introduced with d849f42 to solve #19782. However, we can
solve #19782 without causing the issue. It is enough to save only when
necessary.
Fixes #27338.
|
|/ / / /
| | | |
| | | |
| | | |
| | | |
| | | | |
Some methods were added to public API in
5b14129d8d4ad302b4e11df6bd5c7891b75f393c and they should be not part of
the public API.
|
|\ \ \ \
| |/ / /
|/| | | |
Add a record to target before any callbacks loads the record
|