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.



34
35
36
37
# File 'lib/declarative_policy/condition.rb', line 34

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.



85
86
87
88
89
90
91
92
93
94
# 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

#cached?Boolean

Whether we’ve already computed this condition.

Returns:

  • (Boolean)


49
50
51
# File 'lib/declarative_policy/condition.rb', line 49

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)


42
43
44
45
46
# File 'lib/declarative_policy/condition.rb', line 42

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.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/declarative_policy/condition.rb', line 60

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