mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Use methods to get ScopeRegistry values rather than symbols
We're spending time validating symbol parameters of the ScopeRegistry. It's an internal class, and we can stop validating symbols by converting to methods (you'll automatically get an error if you try to call a method that doesn't exist). Second, since we only have 3 things to keep track of, rather than keep those things in a hash, just break it out in to 3 instance variables. (This is absolutely not a memory bottleneck, but technically this patch will save some memory as the 3 ivars will be embedded in the object rather than require a full st_table for the original wrapper hash)
This commit is contained in:
parent
bcf3752247
commit
73c18888ad
3 changed files with 37 additions and 27 deletions
|
@ -24,19 +24,23 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def current_scope(skip_inherited_scope = false)
|
||||
ScopeRegistry.value_for(:current_scope, self, skip_inherited_scope)
|
||||
ScopeRegistry.current_scope(self, skip_inherited_scope)
|
||||
end
|
||||
|
||||
def current_scope=(scope)
|
||||
ScopeRegistry.set_value_for(:current_scope, self, scope)
|
||||
ScopeRegistry.set_current_scope(self, scope)
|
||||
end
|
||||
|
||||
def global_current_scope(skip_inherited_scope = false)
|
||||
ScopeRegistry.value_for(:global_current_scope, self, skip_inherited_scope)
|
||||
ScopeRegistry.global_current_scope(self, skip_inherited_scope)
|
||||
end
|
||||
|
||||
def global_current_scope=(scope)
|
||||
ScopeRegistry.set_value_for(:global_current_scope, self, scope)
|
||||
ScopeRegistry.set_global_current_scope(self, scope)
|
||||
end
|
||||
|
||||
def scope_registry
|
||||
ScopeRegistry.instance
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -80,34 +84,40 @@ module ActiveRecord
|
|||
VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope, :global_current_scope]
|
||||
|
||||
def initialize
|
||||
@registry = Hash.new { |hash, key| hash[key] = {} }
|
||||
@current_scope = {}
|
||||
@ignore_default_scope = {}
|
||||
@global_current_scope = {}
|
||||
end
|
||||
|
||||
# Obtains the value for a given +scope_type+ and +model+.
|
||||
def value_for(scope_type, model, skip_inherited_scope = false)
|
||||
raise_invalid_scope_type!(scope_type)
|
||||
return @registry[scope_type][model.name] if skip_inherited_scope
|
||||
klass = model
|
||||
base = model.base_class
|
||||
while klass <= base
|
||||
value = @registry[scope_type][klass.name]
|
||||
return value if value
|
||||
klass = klass.superclass
|
||||
VALID_SCOPE_TYPES.each do |type|
|
||||
class_eval <<-eorb, __FILE__, __LINE__
|
||||
def #{type}(model, skip_inherited_scope = false)
|
||||
value_for(@#{type}, model, skip_inherited_scope)
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the +value+ for a given +scope_type+ and +model+.
|
||||
def set_value_for(scope_type, model, value)
|
||||
raise_invalid_scope_type!(scope_type)
|
||||
@registry[scope_type][model.name] = value
|
||||
def set_#{type}(model, value)
|
||||
set_value_for(@#{type}, model, value)
|
||||
end
|
||||
eorb
|
||||
end
|
||||
|
||||
private
|
||||
def raise_invalid_scope_type!(scope_type)
|
||||
if !VALID_SCOPE_TYPES.include?(scope_type)
|
||||
raise ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
|
||||
# Obtains the value for a given +scope_type+ and +model+.
|
||||
def value_for(scope_type, model, skip_inherited_scope = false)
|
||||
return scope_type[model.name] if skip_inherited_scope
|
||||
klass = model
|
||||
base = model.base_class
|
||||
while klass <= base
|
||||
value = scope_type[klass.name]
|
||||
return value if value
|
||||
klass = klass.superclass
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the +value+ for a given +scope_type+ and +model+.
|
||||
def set_value_for(scope_type, model, value)
|
||||
scope_type[model.name] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -173,11 +173,11 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def ignore_default_scope?
|
||||
ScopeRegistry.value_for(:ignore_default_scope, base_class)
|
||||
ScopeRegistry.ignore_default_scope(base_class)
|
||||
end
|
||||
|
||||
def ignore_default_scope=(ignore)
|
||||
ScopeRegistry.set_value_for(:ignore_default_scope, base_class, ignore)
|
||||
ScopeRegistry.set_ignore_default_scope(base_class, ignore)
|
||||
end
|
||||
|
||||
# The ignore_default_scope flag is used to prevent an infinite recursion
|
||||
|
|
|
@ -1259,9 +1259,9 @@ class BasicsTest < ActiveRecord::TestCase
|
|||
|
||||
UnloadablePost.unloadable
|
||||
klass = UnloadablePost
|
||||
assert_not_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, klass)
|
||||
assert_not_nil ActiveRecord::Scoping::ScopeRegistry.current_scope(klass)
|
||||
ActiveSupport::Dependencies.remove_unloadable_constants!
|
||||
assert_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, klass)
|
||||
assert_nil ActiveRecord::Scoping::ScopeRegistry.current_scope(klass)
|
||||
ensure
|
||||
Object.class_eval { remove_const :UnloadablePost } if defined?(UnloadablePost)
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue