Class: Eco::API::Session::Batch::BasePolicy
- Inherits:
-
Object
- Object
- Eco::API::Session::Batch::BasePolicy
- Extended by:
- Common::ClassHierarchy
- Includes:
- 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 ⇒ Integer
max
allowed number of occurrences of the property. -
#min ⇒ 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
Constructor Details
#initialize(attr = nil, _parent: self) ⇒ BasePolicy
Returns a new instance of BasePolicy.
72 73 74 75 76 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 72 def initialize(attr = nil, _parent: self) @_parent = _parent @attr = attr.to_sym @policies = {} end |
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 ⇒ 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 ⇒ 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
41 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 41 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 block.call(policy) 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.
29 30 31 32 33 34 35 36 37 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 29 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.
130 131 132 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 130 def [](attr) @policies[attr.to_sym] end |
#[]=(attr, value) ⇒ Object
136 137 138 139 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 136 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.
124 125 126 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 124 def active?(attr) @policies.key?(attr.to_sym) end |
#compliant?(model, recurse: true) ⇒ Boolean
Returns true
if model
is compliant with the current policy.
144 145 146 147 148 149 150 151 152 153 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 144 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
112 113 114 115 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 112 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.
103 104 105 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 103 def empty? count == 0 end |
#items ⇒ Array<Eco::API::Session::Batch::BasePolicy>
Returns the active subpolicies.
118 119 120 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 118 def items @policies.values end |
#length ⇒ Object
return [Integer] number of declared subpolicies
98 99 100 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 98 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
.
93 94 95 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 93 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
.
86 87 88 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 86 def min?(value) !min || !value|| (min <= value) end |
#subpolicies? ⇒ Boolean
Returns true
if there are active subpolicies, false
otherwise.
108 109 110 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 108 def subpolicies? !empty? end |
#uncompliance(model, recurse: true) ⇒ String
Returns message with what failed to meet compliance.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 175 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
.
164 165 166 167 168 169 170 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 164 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
155 156 157 158 159 160 |
# File 'lib/eco/api/session/batch/base_policy.rb', line 155 def validate!(model) unless compliant?(model) msg = self.uncompliance(model) raise "Uncompliance Exception\n#{msg}" end end |