Class: Grape::Validations::Validators::Base

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Util::Translation
Defined in:
lib/grape/validations/validators/base.rb

Overview

Base class for all parameter validators.

Freeze contract

Validator instances are shared across requests and are frozen after initialization (via .new). All inputs (options, opts, attrs) arrive pre-frozen from the DSL boundary, so subclass ivars derived from them are frozen by construction. Lazy ivar assignment (e.g. memoize, ||=) will raise FrozenError at request time.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs, options, required, scope, opts) ⇒ Base

Creates a new Validator from options specified by a requires or optional directive during parameter definition.

Parameters:

  • attrs (Array)

    names of attributes to which the Validator applies

  • options (Object)

    implementation-dependent Validator options; deep-frozen on assignment

  • required (Boolean)

    attribute(s) are required or optional

  • scope (ParamsScope)

    parent scope for this Validator

  • opts (Hash)

    shared validator options; only :allow_blank and :fail_fast are consulted (other keys ignored, as before)



67
68
69
70
71
72
73
74
75
76
# File 'lib/grape/validations/validators/base.rb', line 67

def initialize(attrs, options, required, scope, opts)
  @attrs = Array(attrs).freeze
  @options = Grape::Util::DeepFreeze.deep_freeze(options)
  @option = @options # TODO: remove in next major release
  @required = required
  @scope = scope
  @opts = SharedOptions.new(**opts.slice(:allow_blank, :fail_fast))
  @exception_message = message(self.class.default_message_key) if self.class.default_message_key
  @iterator = iterator_class.new(@attrs, @scope).freeze
end

Instance Attribute Details

#attrsObject (readonly)

Returns the value of attribute attrs.



18
19
20
# File 'lib/grape/validations/validators/base.rb', line 18

def attrs
  @attrs
end

Class Method Details

.default_message_key(key = nil) ⇒ Object

Declares the default I18n message key used by validation_error!. Subclasses that only need a single fixed error message can declare it at the class level instead of overriding initialize:

class MyValidator < Grape::Validations::Validators::Base
  default_message_key :my_error
end

The key is resolved through message, so a per-option :message override still takes precedence.



40
41
42
43
44
45
46
# File 'lib/grape/validations/validators/base.rb', line 40

def default_message_key(key = nil)
  if key
    @default_message_key = key
  else
    @default_message_key || (superclass.respond_to?(:default_message_key) ? superclass.default_message_key : nil)
  end
end

.inherited(klass) ⇒ Object



52
53
54
55
# File 'lib/grape/validations/validators/base.rb', line 52

def inherited(klass)
  super
  Validations.register(klass)
end

.newObject



48
49
50
# File 'lib/grape/validations/validators/base.rb', line 48

def new(...)
  super.freeze
end

Instance Method Details

#validate(request) ⇒ void

Note:

Override #validate! unless you need to access the entire request.

This method returns an undefined value.

Validates a given request.

Parameters:

Raises:



83
84
85
86
87
# File 'lib/grape/validations/validators/base.rb', line 83

def validate(request)
  return unless scope.should_validate?(request.params)

  validate!(request.params)
end

#validate!(params) ⇒ void

Note:

Override #validate_param! for per-parameter validation, or #validate if you need access to the entire request.

This method returns an undefined value.

Validates a given parameter hash.

Parameters:

  • params (Hash)

    parameters to validate

Raises:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/grape/validations/validators/base.rb', line 95

def validate!(params)
  # we collect errors inside array because
  # there may be more than one error per field
  array_errors = nil

  @iterator.each(params) do |val, attr_name, empty_val|
    next if !scope.required? && empty_val
    next unless scope.meets_dependency?(val, params)

    validate_param!(attr_name, val) if required? || (hash_like?(val) && val.key?(attr_name))
  rescue Grape::Exceptions::Validation => e
    (array_errors ||= []) << e
  end

  raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors
end