Permalink
Browse files

Skip the STI condition when evaluating a default scope

Given a default_scope on a parent of the current class, where that
parent is not the base class, the parent's STI condition would become
attached to the evaluated default scope, and then override the child's
own STI condition.

Instead, we can treat the STI condition as though it is a default scope,
and skip it in this situation: the scope will be merged into the base
relation, which already contains the correct STI condition.

Fixes #22426.
  • Loading branch information...
matthewd committed Jan 11, 2016
1 parent 8ce0175 commit 5c6d3653830465176ed9d37ec210d55d6ab62852
@@ -275,7 +275,7 @@ def cached_find_by_statement(key, &block) # :nodoc:
def relation # :nodoc:
relation = Relation.create(self, arel_table, predicate_builder)
if finder_needs_type_condition?
if finder_needs_type_condition? && !ignore_default_scope?
relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
else
relation
@@ -122,11 +122,11 @@ def build_default_scope(base_rel = nil) # :nodoc:
end
def ignore_default_scope? # :nodoc:
ScopeRegistry.value_for(:ignore_default_scope, self)
ScopeRegistry.value_for(:ignore_default_scope, base_class)
end
def ignore_default_scope=(ignore) # :nodoc:
ScopeRegistry.set_value_for(:ignore_default_scope, self, ignore)
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
end
# The ignore_default_scope flag is used to prevent an infinite recursion
@@ -459,4 +459,18 @@ def test_with_abstract_class_where_clause_should_not_be_duplicated
scope = Bus.all
assert_equal scope.where_clause.ast.children.length, 1
end
def test_sti_conditions_are_not_carried_in_default_scope
ConditionalStiPost.create! body: ''
SubConditionalStiPost.create! body: ''
SubConditionalStiPost.create! title: 'Hello world', body: ''
assert_equal 2, ConditionalStiPost.count
assert_equal 2, ConditionalStiPost.all.to_a.size
assert_equal 3, ConditionalStiPost.unscope(where: :title).to_a.size
assert_equal 1, SubConditionalStiPost.count
assert_equal 1, SubConditionalStiPost.all.to_a.size
assert_equal 2, SubConditionalStiPost.unscope(where: :title).to_a.size
end
end
@@ -263,3 +263,10 @@ class PostWithCommentWithDefaultScopeReferencesAssociation < ActiveRecord::Base
class SerializedPost < ActiveRecord::Base
serialize :title
end
class ConditionalStiPost < Post
default_scope { where(title: 'Untitled') }
end
class SubConditionalStiPost < ConditionalStiPost
end

0 comments on commit 5c6d365

Please sign in to comment.