Class: DataMapper::Validations::ContextualValidators
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/dm-validations/contextual_validators.rb
Overview
Instance Attribute Summary collapse
- #contexts ⇒ Object readonly
Instance Method Summary collapse
-
#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.
-
#execute(named_context, target) ⇒ Boolean
Execute all validators in the named context against the target.
-
#initialize ⇒ ContextualValidators
constructor
A new instance of ContextualValidators.
Constructor Details
#initialize ⇒ ContextualValidators
Returns a new instance of ContextualValidators.
22 23 24 |
# File 'lib/dm-validations/contextual_validators.rb', line 22 def initialize @contexts = {} end |
Instance Attribute Details
#contexts ⇒ Object (readonly)
20 21 22 |
# File 'lib/dm-validations/contextual_validators.rb', line 20 def contexts @contexts end |
Instance Method Details
#clear! ⇒ Object
Clear all named context validators off of the resource
42 43 44 |
# File 'lib/dm-validations/contextual_validators.rb', line 42 def clear! contexts.clear end |
#context(name) ⇒ Array<DataMapper::Validations::GenericValidator>
Return an array of validators for a named context
36 37 38 |
# File 'lib/dm-validations/contextual_validators.rb', line 36 def context(name) contexts[name] ||= [] 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. Optionally only validate dirty properties.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/dm-validations/contextual_validators.rb', line 56 def execute(named_context, target) target.errors.clear! runnable_validators = context(named_context).select{ |validator| validator.execute?(target) } validators = runnable_validators.dup # By default we start the list with the full set of runnable validators. # # 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. # # In the case of a DM::Resource that isn't new, we optimize: # # 1. Eager-load all lazy, not-yet-loaded properties that need # validation, all at once. # # 2. Limit run validators to # - those applied to dirty attributes only, # - those that should always run (presence/absence) # - those that don't reference any real properties (field-less # block validators, validations in virtual attributes) if target.kind_of?(DataMapper::Resource) && !target.new? attrs = target.attributes.keys dirty_attrs = target.dirty_attributes.keys.map{ |p| p.name } validators = runnable_validators.select{|v| !attrs.include?(v.field_name) || dirty_attrs.include?(v.field_name) } # Load all lazy, not-yet-loaded properties that need validation, # all at once. fields_to_load = validators.map{|v| target.class.properties[v.field_name] }.compact.select {|p| p.lazy? && !p.loaded?(target) } target.__send__(:eager_load, fields_to_load) # Finally include any validators that should always run or don't # reference any real properties (field-less block vaildators). validators |= runnable_validators.select do |v| [ MethodValidator, PresenceValidator, AbsenceValidator ].any? do |klass| v.kind_of?(klass) end end end validators.map { |validator| validator.call(target) }.all? end |