Class: DeclarativePolicy::ManifestCondition

Inherits:
Object
  • Object
show all
Defined in:
lib/declarative_policy/condition.rb

Overview

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.

Instance Method Summary collapse

Constructor Details

#initialize(condition, context) ⇒ ManifestCondition

Returns a new instance of ManifestCondition.



52
53
54
55
# File 'lib/declarative_policy/condition.rb', line 52

def initialize(condition, context)
  @condition = condition
  @context = context
end

Instance Method Details

#cache_keyObject

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.



103
104
105
106
107
108
109
110
111
# File 'lib/declarative_policy/condition.rb', line 103

def cache_key
  @cache_key ||=
    case @condition.scope
    when :global  then "/dp/condition/#{@condition.key}"
    when :user    then "/dp/condition/#{@condition.key}/#{user_key}"
    when :subject then "/dp/condition/#{@condition.key}/#{subject_key}"
    else "/dp/condition/#{@condition.key}/#{user_key},#{subject_key}"
    end
end

#cached?Boolean

Whether we’ve already computed this condition.

Returns:

  • (Boolean)


67
68
69
# File 'lib/declarative_policy/condition.rb', line 67

def cached?
  @context.cached?(cache_key)
end

#pass?Boolean

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).

Returns:

  • (Boolean)


60
61
62
63
64
# File 'lib/declarative_policy/condition.rb', line 60

def pass?
  Thread.current[:declarative_policy_current_runner_state]&.register(self)

  @context.cache(cache_key) { @condition.compute(@context) }
end

#scoreObject

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.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/declarative_policy/condition.rb', line 78

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 == :user_and_subject

  # 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