@author Guy van den Berg @since 0.9
Create a new validator of the given klazz and push it onto the requested context for each of the attributes in attributes
@param [DataMapper::Validations::GenericValidator] validator_class
Validator class, example: DataMapper::Validations::LengthValidator
@param [Array
Attribute names given to validation macro, example: [:first_name, :last_name] in validates_presence_of :first_name, :last_name
@param [Hash] options
Options supplied to validation macro, example: {:context=>:default, :maximum=>50, :allow_nil=>true, :message=>nil}
@option [Symbol] :context
the context in which the new validator should be run
@option [Boolean] :allow_nil
whether or not the new validator should allow nil values
@option [Boolean] :message
the error message the new validator will provide on validation failure
# File lib/dm-validations/contextual_validators.rb, line 78 78: def add(validator_class, *attributes) 79: options = attributes.last.kind_of?(Hash) ? attributes.pop.dup : {} 80: normalize_options(options) 81: validator_options = DataMapper::Ext::Hash.except(options, :context) 82: 83: attributes.each do |attribute| 84: # TODO: is :context part of the Validator state (ie, intrinsic), 85: # or is it just membership in a collection? 86: validator = validator_class.new(attribute, validator_options) 87: attribute_validators = self.attribute(attribute) 88: attribute_validators << validator unless attribute_validators.include?(validator) 89: 90: options[:context].each do |context| 91: context_validators = self.context(context) 92: next if context_validators.include?(validator) 93: context_validators << validator 94: # TODO: eliminate this, then eliminate the @model ivar entirely 95: Validations::ClassMethods.create_context_instance_methods(@model, context) if @model 96: end 97: end 98: end
Assert that the given context is valid for this model
@param [Symbol] context
the context to test
@raise [InvalidContextError]
raised if the context is not valid for this model
@api private
TODO: is this method actually needed?
# File lib/dm-validations/contextual_validators.rb, line 172 172: def assert_valid(context) 173: unless valid_context?(context) 174: raise InvalidContextError, "#{context} is an invalid context, known contexts are #{contexts.keys.inspect}" 175: end 176: end
Return an array of validators for a named property
@param [Symbol]
Property name for which to return validators
@return [Array
An array of validators bound to the given property
# File lib/dm-validations/contextual_validators.rb, line 47 47: def attribute(name) 48: attributes[name] ||= OrderedSet.new 49: end
Clear all named context validators off of the resource
# File lib/dm-validations/contextual_validators.rb, line 53 53: def clear! 54: contexts.clear 55: attributes.clear 56: end
Return an array of validators for a named context
@param [String]
Context name for which to return validators
@return [Array
An array of validators bound to the given context
# File lib/dm-validations/contextual_validators.rb, line 37 37: def context(name) 38: contexts[name] ||= OrderedSet.new 39: end
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.
@return [Symbol]
the current validation context from the stack (if valid for this model), nil if no context is on the stack and no contexts are defined for this model, or :default if the context on the stack is invalid for this model or no context is on the stack and this model has at least one validation context
@api private
TODO: simplify the semantics of #, #
# File lib/dm-validations/contextual_validators.rb, line 141 141: def current_context 142: context = Validations::Context.current 143: valid_context?(context) ? context : :default 144: end
Execute all validators in the named context against the target. Load together any properties that are designated lazy but are not yet loaded.
@param [Symbol] named_context
the context we are validating against
@param [Object] target
the resource that we are validating
@return [Boolean]
true if all are valid, otherwise false
# File lib/dm-validations/contextual_validators.rb, line 188 188: def execute(named_context, target) 189: target.errors.clear! 190: 191: available_validators = context(named_context) 192: executable_validators = available_validators.select { |v| v.execute?(target) } 193: 194: # In the case of a new Resource or regular ruby class instance, 195: # everything needs to be validated completely, and no eager-loading 196: # logic should apply. 197: # 198: if target.kind_of?(DataMapper::Resource) && !target.new? 199: load_validated_properties(target, executable_validators) 200: end 201: executable_validators.map { |validator| validator.call(target) }.all? 202: end
Load all lazy, not-yet-loaded properties that need validation, all at once.
# File lib/dm-validations/contextual_validators.rb, line 206 206: def load_validated_properties(resource, validators) 207: properties = resource.model.properties 208: 209: properties_to_load = validators.map { |validator| 210: properties[validator.field_name] 211: }.compact.select { |property| 212: property.lazy? && !property.loaded?(resource) 213: } 214: 215: resource.__send__(:eager_load, properties_to_load) 216: end
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
@param [Hash] options
the options to be normalized
@param [NilClass, Hash] defaults
default keys/values to set on normalized options
@return [Hash]
the normalized options
@api private
# File lib/dm-validations/contextual_validators.rb, line 113 113: def normalize_options(options, defaults = nil) 114: context = [ 115: options.delete(:group), 116: options.delete(:on), 117: options.delete(:when), 118: options.delete(:context) 119: ].compact.first 120: 121: options[:context] = Array(context || :default) 122: options.update(defaults) unless defaults.nil? 123: options 124: end
Test if the context is valid for the model
@param [Symbol] context
the context to test
@return [Boolean]
true if the context is valid for the model
@api private
TODO: investigate removing the `contexts.empty?` test here.
# File lib/dm-validations/contextual_validators.rb, line 157 157: def valid_context?(context) 158: contexts.empty? || contexts.include?(context) 159: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.