-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ActiveRecord 4.2.3 regression: unscope mutates source relation's where_values #20722
Comments
I'm currently working on a tescase using the ar template, will post a gist asap. |
While writing a testcase I noticed that There is no indication in the docs that |
Here's the testcase: https://gist.github.com/21dc7e7496839ae06e07 On rails 4.2.3 it fails with the following exception:
Interestingly it also fails on older versions, eg. 4.2.2, 4.1.0, 4.0.0 because both the
So it seems |
This might be related to #20721. |
@felixbuenemann the title mentions regression but since it also fails on older versions that's not really the case. Is it possible to create a gist that started failing on |
@senny well it fails with an exception on 4.2.3 which it didn't before. I only noticed in the process that unscope was already mutating the source previously. I could change the gist to assert on the size of where_values and bind_values as written in the initial post. |
The current gist is fine, I spent the morning on this and the related issues. I have a fix pretty much done, just had to run into meetings. Should have it finished tonight or tomorrow. |
@sgrif Thanks for the update! |
The changes introduced to through associations in c80487e were quite interesting. Changing `relation.merge!(scope)` to `relation = relation.merge(scope)` should in theory never cause any changes in behavior. The subtle breakage led to a surprising conclusion. The old code wasn't doing anything! Since `merge!` calls `instance_exec` when given a proc, and most scopes will look something like `has_many :foos, -> { where(foo: :bar) }`, if we're not capturing the return value, it's a no-op. However, removing the `merge` causes `unscope` to break. While we're merging in the rest of the chain elsewhere, we were never merging in `unscope` values, causing a breakage on associations where a default scope was being unscoped in an association scope (yuk!). This is subtly related to #20722, since it appears we were previously relying on this mutability. Fixes #20721. Fixes #20727.
The changes introduced to through associations in c80487e were quite interesting. Changing `relation.merge!(scope)` to `relation = relation.merge(scope)` should in theory never cause any changes in behavior. The subtle breakage led to a surprising conclusion. The old code wasn't doing anything! Since `merge!` calls `instance_exec` when given a proc, and most scopes will look something like `has_many :foos, -> { where(foo: :bar) }`, if we're not capturing the return value, it's a no-op. However, removing the `merge` causes `unscope` to break. While we're merging in the rest of the chain elsewhere, we were never merging in `unscope` values, causing a breakage on associations where a default scope was being unscoped in an association scope (yuk!). This is subtly related to #20722, since it appears we were previously relying on this mutability. Fixes #20721. Fixes #20727.
This was fixed by 449241c |
I'll confirm when I can, but that test was passing for me. |
This was already fixed on master as part of a routine refactoring to remove all mutation of any `_values` attributes, but this particular case was still causing a bug on 4-2-stable. Fixes #20722.
Fixed in 21e05a0 |
Thanks, works fine on 4-2-stable! |
Perhaps the original author thought it didn't because there was no `where_unscoping` override defined for 4.2 but it inherits from 4.1. It doesn't hurt to do the test anyway, except that the unscope call had to be changed to `unscope!` in order for the SQL check to pass. It should have been `unscope!` all along and it only worked because of rails/rails#20722.
There is a regression in ActiveRecord 4.2.3 compared to 4.2.2 related to
unscope
.Calling
unscope
on a relation modifies thewhere_values
in the input relation instead of only in the returned relation:The text was updated successfully, but these errors were encountered: