From d13f54d50a166d49c683f79d49341185788faed8 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Tue, 18 Jul 2017 10:22:05 +0900 Subject: [PATCH] Fix unscoping `default_scope` in STI associations Since 5c71000, it has lost to be able to unscope `default_scope` in STI associations. This change will use `.empty_scope?` instead of `.values.empty?` to regard as an empty scope if only have `type_condition`. --- activerecord/lib/active_record/reflection.rb | 6 ++++-- activerecord/lib/active_record/relation.rb | 4 ++++ .../test/cases/scoping/default_scoping_test.rb | 16 ++++++++++++++++ activerecord/test/models/comment.rb | 1 + activerecord/test/schema/schema.rb | 1 + 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 4f53280b5c..1026e20f79 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -219,8 +219,10 @@ module ActiveRecord end def klass_join_scope(table, predicate_builder) # :nodoc: - if klass.current_scope && klass.current_scope.values.empty? - klass.unscoped + current_scope = klass.current_scope + + if current_scope && current_scope.empty_scope? + build_scope(table, predicate_builder) else klass.default_scoped(build_scope(table, predicate_builder)) end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index c5d98e970a..d9e1e5c39c 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -642,6 +642,10 @@ module ActiveRecord "#<#{self.class.name} [#{entries.join(', ')}]>" end + def empty_scope? # :nodoc: + @values == klass.unscoped.values + end + protected def load_records(records) diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb index a5061cfce7..83f3868f3f 100644 --- a/activerecord/test/cases/scoping/default_scoping_test.rb +++ b/activerecord/test/cases/scoping/default_scoping_test.rb @@ -392,6 +392,22 @@ class DefaultScopingTest < ActiveRecord::TestCase Comment.joins(:post).to_a end + def test_sti_association_with_unscoped_not_affected_by_default_scope + post = posts(:thinking) + comments = [comments(:does_it_hurt)] + + post.special_comments.update_all(deleted_at: Time.now) + + assert_raises(ActiveRecord::RecordNotFound) { Post.joins(:special_comments).find(post.id) } + assert_equal [], post.special_comments + + SpecialComment.unscoped do + assert_equal post, Post.joins(:special_comments).find(post.id) + assert_equal comments, Post.joins(:special_comments).find(post.id).special_comments + assert_equal comments, Post.eager_load(:special_comments).find(post.id).special_comments + end + end + def test_default_scope_select_ignored_by_aggregations assert_equal DeveloperWithSelect.all.to_a.count, DeveloperWithSelect.count end diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb index eecf923046..dc2d421cd7 100644 --- a/activerecord/test/models/comment.rb +++ b/activerecord/test/models/comment.rb @@ -54,6 +54,7 @@ class Comment < ActiveRecord::Base end class SpecialComment < Comment + default_scope { where(deleted_at: nil) } end class SubSpecialComment < SpecialComment diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index f534e9c00e..90185ff6c5 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -189,6 +189,7 @@ ActiveRecord::Schema.define do t.string :resource_id t.string :resource_type t.integer :developer_id + t.datetime :deleted_at end create_table :companies, force: true do |t|