提交 5c71000d 编写于 作者: S Sean Griffin

Post.joins(:users) should not be affected by `User.current_scope`

This change was introduced by #18109. The intent of that change was to
specifically apply `unscoped`, not to allow all changes to
`current_scope` to affect the join. The idea of allowing `current_scope`
to affect joins is interesting and potentially more consistent, but has
sever problems associated with it. The fact that we're specifically
stripping out joins indicates one such problem (and potentially leads to
invalid queries).

Ultimately it's difficult to reason about what `Posts.joins(:users)`
actually means if it's affected by `User.current_scope`, and it's
difficult to specifically control what does or doesn't get added. If we
were starting from scratch, I don't think I'd have `joins` be affected
by `default_scope` either, but that's too big of a breaking change to
make at this point.

With this change, we no longer apply `current_scope` when bringing in
joins, with the singular exception of the motivating use case which
introduced this bug, which is providing a way to *opt-out* of having the
default scope apply to joins.

Fixes #29338.
上级 3bda7ff7
* `Relation#joins` is no longer affected by the target model's
`current_scope`, with the exception of `unscoped`.
Fixes #29338.
*Sean Griffin*
* Change sqlite3 boolean serialization to use 1 and 0
SQLite natively recognizes 1 and 0 as true and false, but does not natively
......
......@@ -219,10 +219,8 @@ def join_scopes(table, predicate_builder) # :nodoc:
end
def klass_join_scope(table, predicate_builder) # :nodoc:
if klass.current_scope
klass.current_scope.clone.tap { |scope|
scope.joins_values = scope.left_outer_joins_values = [].freeze
}
if klass.current_scope && klass.current_scope.values.empty?
klass.unscoped
else
klass.default_scoped(build_scope(table, predicate_builder))
end
......
......@@ -377,6 +377,16 @@ def test_default_scope_with_joins
Comment.joins(:post).count
end
def test_joins_not_affected_by_scope_other_than_default_or_unscoped
without_scope_on_post = Comment.joins(:post).to_a
with_scope_on_post = nil
Post.where(id: [1, 5, 6]).scoping do
with_scope_on_post = Comment.joins(:post).to_a
end
assert_equal with_scope_on_post, without_scope_on_post
end
def test_unscoped_with_joins_should_not_have_default_scope
assert_equal SpecialPostWithDefaultScope.unscoped { Comment.joins(:special_post_with_default_scope).to_a },
Comment.joins(:post).to_a
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册