From 2e018361c7c51e36d1d98bf770b7456d78dee68b Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Thu, 7 Feb 2019 19:40:10 +0900 Subject: Refactor around scoping Don't use `false` as special value to skip to find inherited scope, we could use `skip_inherited_scope = true`, and move `_scoping` back on Relation. --- activerecord/lib/active_record/relation.rb | 11 +++++++++-- activerecord/lib/active_record/relation/spawn_methods.rb | 2 +- activerecord/lib/active_record/scoping.rb | 9 ++++----- activerecord/lib/active_record/scoping/default.rb | 9 +-------- activerecord/lib/active_record/scoping/named.rb | 3 +-- 5 files changed, 16 insertions(+), 18 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index bab00ef065..ab3d6f7222 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -312,12 +312,12 @@ module ActiveRecord # Please check unscoped if you want to remove all previous scopes (including # the default_scope) during the execution of a block. def scoping - @delegate_to_klass && klass.current_scope ? yield : klass._scoping(self) { yield } + @delegate_to_klass && klass.current_scope(true) ? yield : _scoping(self) { yield } end def _exec_scope(*args, &block) # :nodoc: @delegate_to_klass = true - instance_exec(*args, &block) || self + _scoping(nil) { instance_exec(*args, &block) || self } ensure @delegate_to_klass = false end @@ -632,6 +632,13 @@ module ActiveRecord end private + def _scoping(scope) + previous, klass.current_scope = klass.current_scope(true), scope + yield + ensure + klass.current_scope = previous + end + def _substitute_values(values) values.map do |name, value| attr = arel_attribute(name) diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index d758e289ca..8cf4fc469f 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -8,7 +8,7 @@ module ActiveRecord module SpawnMethods # This is overridden by Associations::CollectionProxy def spawn #:nodoc: - @delegate_to_klass && klass.current_scope ? klass.all : clone + @delegate_to_klass && klass.current_scope(true) ? klass.all : clone end # Merges in the conditions from other, if other is an ActiveRecord::Relation. diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb index c3a56b2174..35e9dcbffc 100644 --- a/activerecord/lib/active_record/scoping.rb +++ b/activerecord/lib/active_record/scoping.rb @@ -27,10 +27,9 @@ module ActiveRecord ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope) end - private - def current_scope=(scope) - ScopeRegistry.set_value_for(:current_scope, self, scope) - end + def current_scope=(scope) + ScopeRegistry.set_value_for(:current_scope, self, scope) + end end def populate_with_current_scope_attributes # :nodoc: @@ -84,7 +83,7 @@ module ActiveRecord base = model.base_class while klass <= base value = @registry[scope_type][klass.name] - return value || nil unless value.nil? + return value if value klass = klass.superclass end end diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb index 6caf9b3251..8c612df27a 100644 --- a/activerecord/lib/active_record/scoping/default.rb +++ b/activerecord/lib/active_record/scoping/default.rb @@ -31,14 +31,7 @@ module ActiveRecord # Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10" # } def unscoped - block_given? ? _scoping(relation) { yield } : relation - end - - def _scoping(relation) # :nodoc: - previous, self.current_scope = current_scope(true), relation - yield - ensure - self.current_scope = previous + block_given? ? relation.scoping { yield } : relation end # Are there attributes associated with this scope? diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb index 987e6bd63f..5278eb29a9 100644 --- a/activerecord/lib/active_record/scoping/named.rb +++ b/activerecord/lib/active_record/scoping/named.rb @@ -180,8 +180,7 @@ module ActiveRecord if body.respond_to?(:to_proc) singleton_class.define_method(name) do |*args| - scope = all - scope = _scoping(false) { scope._exec_scope(*args, &body) } + scope = all._exec_scope(*args, &body) scope = scope.extending(extension) if extension scope end -- cgit v1.2.3