Class: Eco::API::Session::Batch::BasePolicy
- Extended by:
- Common::ClassHierarchy
- Includes:
- Language::Methods::DslAble, Enumerable
- Defined in:
- lib/eco/api/session/batch/base_policy.rb
Overview
Helper class to build a hierarchical model of policies
Direct Known Subclasses
Instance Attribute Summary collapse
-
#attr(as_namespace: false) ⇒ Symbol
readonly
the Symbol
name
of the current policy. -
#max(value = :unused) ⇒ Integer
max
allowed number of occurrences of the property. -
#min(value = :unused) ⇒ Integer
min
required number of occurrences of the property.
Attributes included from Common::ClassHierarchy
Class Method Summary collapse
-
.policy_attrs(*attrs) ⇒ Object
Attributes of this level of the model that should be included.
-
.policy_class(key) ⇒ Eco::API::Session::Batch::BasePolicy
If the class for
key
exists, it returns it.
Instance Method Summary collapse
-
#[](attr) ⇒ Array<Eco::API::Session::Batch::BasePolicy>
The used subpolicies.
- #[]=(attr, value) ⇒ Object
-
#active?(attr) ⇒ Boolean
If
attr
is an active subpolicy. -
#compliant?(model, recurse: true) ⇒ Boolean
true
ifmodel
is compliant with the current policy. - #each(&block) ⇒ Object
-
#empty? ⇒ Boolean
true
if there are no active subpolicies,false
otherwise. -
#initialize(attr = nil, _parent: self) ⇒ BasePolicy
constructor
A new instance of BasePolicy.
-
#items ⇒ Array<Eco::API::Session::Batch::BasePolicy>
The active subpolicies.
-
#length ⇒ Object
return [Integer] number of declared subpolicies.
-
#max?(value) ⇒ Boolen
true
ifvalue
is lesser or equal tomin
. -
#min?(value) ⇒ Boolen
true
ifvalue
is grater or equal tomin
. -
#subpolicies? ⇒ Boolean
true
if there are active subpolicies,false
otherwise. -
#uncompliance(model, recurse: true) ⇒ String
Message with what failed to meet compliance.
-
#uncompliant(model) ⇒ Array<Eco::API::Session::Batch::BasePolicy>
non-compliant policies for the
model
. - #validate!(model) ⇒ Object
Methods included from Common::ClassHierarchy
Methods included from Common::ClassHelpers
#class_resolver, #descendants, #descendants?, #inheritable_attrs, #inheritable_class_vars, #inherited, #instance_variable_name, #new_class, #resolve_class, #to_constant
Methods included from Language::Methods::DslAble
#evaluate, #method_missing, #respond_to_missing?
Constructor Details
#initialize(attr = nil, _parent: self) ⇒ BasePolicy
Returns a new instance of BasePolicy.
71 72 73 74 75 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 71 def initialize(attr = nil, _parent: self) @_parent = _parent @attr = attr.to_sym @policies = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Eco::Language::Methods::DslAble
Instance Attribute Details
#attr(as_namespace: false) ⇒ Symbol (readonly)
the Symbol name
of the current policy
21 22 23 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 21 def attr @attr end |
#max(value = :unused) ⇒ Integer
max
allowed number of occurrences of the property
21 22 23 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 21 def max @max end |
#min(value = :unused) ⇒ Integer
min
required number of occurrences of the property
21 22 23 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 21 def min @min end |
Class Method Details
.policy_attrs(*attrs) ⇒ Object
Attributes of this level of the model that should be included
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 42 def policy_attrs(*attrs) attrs = attrs.map(&:to_sym) attrs.each do |attr| method = attr.to_s.freeze var = "@#{method}".freeze define_method(method) do |&block| unless policy = self[attr] klass = self.class.policy_class(attr) policy = self[attr] = klass.new(attr, _parent: self) end if block policy.evaluate(policy, &block) self else policy end end end end |
.policy_class(key) ⇒ Eco::API::Session::Batch::BasePolicy
for this to work, key
should be one of the submodels of the current class' model
If the class for key
exists, it returns it. Otherwise it generates it.
30 31 32 33 34 35 36 37 38 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 30 def policy_class(key) key = key.to_sym.freeze class_name = to_constant(key) new_class(class_name, inherits: Eco::API::Session::Batch::BasePolicy) do |klass| klass.model = model[key] klass.policy_attrs *klass.model_attrs end end |
Instance Method Details
#[](attr) ⇒ Array<Eco::API::Session::Batch::BasePolicy>
Returns the used subpolicies.
139 140 141 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 139 def [](attr) @policies[attr.to_sym] end |
#[]=(attr, value) ⇒ Object
145 146 147 148 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 145 def []=(attr, value) raise "Expected object of Eco::API::Session::Batch::BasePolicy. Given #{value.class}" unless value.is_a?(Eco::API::Session::Batch::BasePolicy) @policies[attr.to_sym] = value end |
#active?(attr) ⇒ Boolean
Returns if attr
is an active subpolicy.
133 134 135 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 133 def active?(attr) @policies.key?(attr.to_sym) end |
#compliant?(model, recurse: true) ⇒ Boolean
Returns true
if model
is compliant with the current policy.
153 154 155 156 157 158 159 160 161 162 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 153 def compliant?(model, recurse: true) unless hash = model_to_hash(model) raise "Expected 'model' to be a Hash (or hashable) object. Given: #{model}" end value = model_attr(hash) good = !model_attr?(hash) || (min?(value) && max?(value)) #pp "batch_policy: '#{attr}' - #{value}: 'min' #{min?(value)}; 'max' #{max?(value)}" good &&= all? {|active| active.compliant?(model, recurse: recurse)} if recurse good end |
#each(&block) ⇒ Object
121 122 123 124 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 121 def each(&block) return to_enum(:each) unless block items.each(&block) end |
#empty? ⇒ Boolean
Returns true
if there are no active subpolicies, false
otherwise.
112 113 114 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 112 def empty? count == 0 end |
#items ⇒ Array<Eco::API::Session::Batch::BasePolicy>
Returns the active subpolicies.
127 128 129 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 127 def items @policies.values end |
#length ⇒ Object
return [Integer] number of declared subpolicies
107 108 109 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 107 def length count end |
#max?(value) ⇒ Boolen
if there's no max
defined, it always returns true
Returns true
if value
is lesser or equal to min
.
102 103 104 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 102 def max?(value) !max || !value || (max >= value) end |
#min?(value) ⇒ Boolen
if there's no min
defined, it always returns true
Returns true
if value
is grater or equal to min
.
95 96 97 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 95 def min?(value) !min || !value|| (min <= value) end |
#subpolicies? ⇒ Boolean
Returns true
if there are active subpolicies, false
otherwise.
117 118 119 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 117 def subpolicies? !empty? end |
#uncompliance(model, recurse: true) ⇒ String
Returns message with what failed to meet compliance.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 184 def uncompliance(model, recurse: true) unless hash = model_to_hash(model) raise "Expected 'model' to be a Hash (or hashable) object. Given: #{model}" end msg = "" unless compliant?(hash, recurse: false) value = model_attr(hash) msg += "'#{attr(as_namespace: true)}' fails to meet: " msg += " [ min(#{min}) >= #{value}] " unless min?(value) msg += " [ max(#{max}) <= #{value}] " unless max?(value) msg += "\n" end if recurse map do |active| active.uncompliance(hash, recurse: true) end.compact.tap do |msgs| msg += "\n" + msgs.join("\n") unless msgs.empty? end end msg end |
#uncompliant(model) ⇒ Array<Eco::API::Session::Batch::BasePolicy>
Returns non-compliant policies for the model
.
173 174 175 176 177 178 179 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 173 def uncompliant(model) each_with_object([]) do |active, arr| arr.concat(active.uncompliant(model)) end.tap do |arr| arr.unshift(self) unless compliant?(model, recurse: false) end end |
#validate!(model) ⇒ Object
164 165 166 167 168 169 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 164 def validate!(model) unless compliant?(model) msg = self.uncompliance(model) raise "Uncompliance Exception\n#{msg}" end end |