Class: DataMapper::Validations::ContextualValidators
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/dm-validations/contextual_validators.rb
Overview
Instance Attribute Summary collapse
- #attributes ⇒ Object readonly
- #contexts ⇒ Object readonly
Instance Method Summary collapse
-
#add(validator_class, *attributes) ⇒ Object
Create a new validator of the given klazz and push it onto the requested context for each of the attributes in
attributes
. -
#assert_valid(context) ⇒ Object
private
Assert that the given context is valid for this model.
-
#attribute(name) ⇒ Array<DataMapper::Validations::GenericValidator>
Return an array of validators for a named property.
-
#clear! ⇒ Object
Clear all named context validators off of the resource.
-
#context(name) ⇒ Array<DataMapper::Validations::GenericValidator>
Return an array of validators for a named context.
-
#current_context ⇒ Symbol
private
Returns the current validation context on the stack if valid for this model, nil if no contexts are defined for the model (and no contexts are on the validation stack), or :default if the current context is invalid for this model or no contexts have been defined for this model and no context is on the stack.
-
#execute(named_context, target) ⇒ Boolean
Execute all validators in the named context against the target.
-
#initialize(model = nil) ⇒ ContextualValidators
constructor
A new instance of ContextualValidators.
-
#load_validated_properties(resource, validators) ⇒ Object
Load all lazy, not-yet-loaded properties that need validation, all at once.
-
#normalize_options(options, defaults = nil) ⇒ Hash
private
Clean up the argument list and return a opts hash, including the merging of any default opts.
-
#valid_context?(context) ⇒ Boolean
private
Test if the context is valid for the model.
Constructor Details
#initialize(model = nil) ⇒ ContextualValidators
Returns a new instance of ContextualValidators.
21 22 23 24 25 |
# File 'lib/dm-validations/contextual_validators.rb', line 21 def initialize(model = nil) @model = model @contexts = {} @attributes = {} end |
Instance Attribute Details
#attributes ⇒ Object (readonly)
19 20 21 |
# File 'lib/dm-validations/contextual_validators.rb', line 19 def attributes @attributes end |
#contexts ⇒ Object (readonly)
19 20 21 |
# File 'lib/dm-validations/contextual_validators.rb', line 19 def contexts @contexts end |
Instance Method Details
#add(validator_class, *attributes) ⇒ Object
Create a new validator of the given klazz and push it onto the requested context for each of the attributes in attributes
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/dm-validations/contextual_validators.rb', line 78 def add(validator_class, *attributes) = attributes.last.kind_of?(Hash) ? attributes.pop.dup : {} () = DataMapper::Ext::Hash.except(, :context) attributes.each do |attribute| # TODO: is :context part of the Validator state (ie, intrinsic), # or is it just membership in a collection? validator = validator_class.new(attribute, ) attribute_validators = self.attribute(attribute) attribute_validators << validator unless attribute_validators.include?(validator) [:context].each do |context| context_validators = self.context(context) next if context_validators.include?(validator) context_validators << validator # TODO: eliminate this, then eliminate the @model ivar entirely Validations::ClassMethods.create_context_instance_methods(@model, context) if @model end end end |
#assert_valid(context) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Assert that the given context is valid for this model
TODO: is this method actually needed?
172 173 174 175 176 |
# File 'lib/dm-validations/contextual_validators.rb', line 172 def assert_valid(context) unless valid_context?(context) raise InvalidContextError, "#{context} is an invalid context, known contexts are #{contexts.keys.inspect}" end end |
#attribute(name) ⇒ Array<DataMapper::Validations::GenericValidator>
Return an array of validators for a named property
47 48 49 |
# File 'lib/dm-validations/contextual_validators.rb', line 47 def attribute(name) attributes[name] ||= OrderedSet.new end |
#clear! ⇒ Object
Clear all named context validators off of the resource
53 54 55 56 |
# File 'lib/dm-validations/contextual_validators.rb', line 53 def clear! contexts.clear attributes.clear end |
#context(name) ⇒ Array<DataMapper::Validations::GenericValidator>
Return an array of validators for a named context
37 38 39 |
# File 'lib/dm-validations/contextual_validators.rb', line 37 def context(name) contexts[name] ||= OrderedSet.new end |
#current_context ⇒ Symbol
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the current validation context on the stack if valid for this model, nil if no contexts are defined for the model (and no contexts are on the validation stack), or :default if the current context is invalid for this model or no contexts have been defined for this model and no context is on the stack.
TODO: simplify the semantics of #current_context, #valid?
141 142 143 144 |
# File 'lib/dm-validations/contextual_validators.rb', line 141 def current_context context = Validations::Context.current valid_context?(context) ? context : :default end |
#execute(named_context, target) ⇒ Boolean
Execute all validators in the named context against the target. Load together any properties that are designated lazy but are not yet loaded.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/dm-validations/contextual_validators.rb', line 188 def execute(named_context, target) target.errors.clear! available_validators = context(named_context) executable_validators = available_validators.select { |v| v.execute?(target) } # In the case of a new Resource or regular ruby class instance, # everything needs to be validated completely, and no eager-loading # logic should apply. # if target.kind_of?(DataMapper::Resource) && !target.new? load_validated_properties(target, executable_validators) end executable_validators.map { |validator| validator.call(target) }.all? end |
#load_validated_properties(resource, validators) ⇒ Object
Load all lazy, not-yet-loaded properties that need validation, all at once.
206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/dm-validations/contextual_validators.rb', line 206 def load_validated_properties(resource, validators) properties = resource.model.properties properties_to_load = validators.map { |validator| properties[validator.field_name] }.compact.select { |property| property.lazy? && !property.loaded?(resource) } resource.__send__(:eager_load, properties_to_load) end |
#normalize_options(options, defaults = nil) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Clean up the argument list and return a opts hash, including the merging of any default opts. Set the context to default if none is provided. Also allow :context to be aliased to :on, :when & :group
113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/dm-validations/contextual_validators.rb', line 113 def (, defaults = nil) context = [ .delete(:group), .delete(:on), .delete(:when), .delete(:context) ].compact.first [:context] = Array(context || :default) .update(defaults) unless defaults.nil? end |
#valid_context?(context) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Test if the context is valid for the model
TODO: investigate removing the ‘contexts.empty?` test here.
157 158 159 |
# File 'lib/dm-validations/contextual_validators.rb', line 157 def valid_context?(context) contexts.empty? || contexts.include?(context) end |