class DeclarativePolicy::ManifestCondition
In contrast to a Condition
, a ManifestCondition
contains a Condition
and a context object, and is capable of calculating a result itself. This is the return value of Base#condition
.
Public Class Methods
# File lib/declarative_policy/condition.rb, line 34 def initialize(condition, context) @condition = condition @context = context end
Public Instance Methods
Whether we've already computed this condition.
# File lib/declarative_policy/condition.rb, line 47 def cached? @context.cached?(cache_key) end
The main entry point - does this condition pass? We reach into the context's cache here so that we can share in the global cache (often RequestStore or similar).
# File lib/declarative_policy/condition.rb, line 42 def pass? @context.cache(cache_key) { @condition.compute(@context) } end
This is used to score Rule::Condition
. See Rule::Condition#score
and Runner#steps_by_score
for how scores are used.
The number here is intended to represent, abstractly, how expensive it would be to calculate this condition.
See cache_key
for info about @condition.scope.
# File lib/declarative_policy/condition.rb, line 58 def score # If we've been cached, no computation is necessary. return 0 if cached? # Use the override from condition(score: ...) if present return @condition.manual_score if @condition.manual_score # Global scope rules are cheap due to max cache sharing return 2 if @condition.scope == :global # "Normal" rules can't share caches with any other policies return 16 if @condition.scope == :normal # otherwise, we're :user or :subject scope, so it's 4 if # the caller has declared a preference return 4 if @condition.scope == DeclarativePolicy.preferred_scope # and 8 for all other :user or :subject scope conditions. 8 end
Private Instance Methods
This method controls the caching for the condition. This is where the condition(scope: …) option comes into play. Notice that depending on the scope, we may cache only by the user or only by the subject, resulting in sharing across different policy objects.
# File lib/declarative_policy/condition.rb, line 85 def cache_key @cache_key ||= case @condition.scope when :normal then "/dp/condition/#{@condition.key}/#{user_key},#{subject_key}" when :user then "/dp/condition/#{@condition.key}/#{user_key}" when :subject then "/dp/condition/#{@condition.key}/#{subject_key}" when :global then "/dp/condition/#{@condition.key}" else raise 'invalid scope' end end
# File lib/declarative_policy/condition.rb, line 100 def subject_key Cache.subject_key(@context.subject) end
# File lib/declarative_policy/condition.rb, line 96 def user_key Cache.user_key(@context.user) end