class Grape::Validations::ParamsScope
Attributes
element[RW]
parent[RW]
Public Class Methods
new(opts, &block)
click to toggle source
# File lib/grape/validations.rb, line 87 def initialize(opts, &block) @element = opts[:element] @parent = opts[:parent] @api = opts[:api] @optional = opts[:optional] || false @type = opts[:type] @declared_params = [] instance_eval(&block) configure_declared_params end
Public Instance Methods
exactly_one_of(*attrs)
click to toggle source
# File lib/grape/validations.rb, line 137 def exactly_one_of(*attrs) validates(attrs, exactly_one_of: true) end
full_name(name)
click to toggle source
# File lib/grape/validations.rb, line 172 def full_name(name) return "#{@parent.full_name(@element)}[#{name}]" if @parent name.to_s end
group(*attrs, &block)
click to toggle source
# File lib/grape/validations.rb, line 141 def group(*attrs, &block) requires(*attrs, &block) end
mutually_exclusive(*attrs)
click to toggle source
# File lib/grape/validations.rb, line 133 def mutually_exclusive(*attrs) validates(attrs, mutual_exclusion: true) end
optional(*attrs, &block)
click to toggle source
# File lib/grape/validations.rb, line 121 def optional(*attrs, &block) orig_attrs = attrs validations = {} validations.merge!(attrs.pop) if attrs.last.is_a?(Hash) validations[:type] ||= Array if block_given? validates(attrs, validations) block_given? ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs) end
params(params)
click to toggle source
# File lib/grape/validations.rb, line 145 def params(params) params = @parent.params(params) if @parent if @element if params.is_a?(Array) params = params.flat_map { |el| el[@element] || {} } elsif params.is_a?(Hash) params = params[@element] || {} else params = {} end end params end
requires(*attrs, &block)
click to toggle source
# File lib/grape/validations.rb, line 106 def requires(*attrs, &block) orig_attrs = attrs.clone opts = attrs.last.is_a?(Hash) ? attrs.pop : nil if opts && opts[:using] require_required_and_optional_fields(attrs.first, opts) else validate_attributes(attrs, opts, &block) block_given? ? new_scope(orig_attrs, &block) : push_declared_params(attrs) end end
root?()
click to toggle source
# File lib/grape/validations.rb, line 177 def root? !@parent end
should_validate?(parameters)
click to toggle source
# File lib/grape/validations.rb, line 100 def should_validate?(parameters) return false if @optional && params(parameters).respond_to?(:all?) && params(parameters).all?(&:blank?) return true if parent.nil? parent.should_validate?(parameters) end
use(*names)
click to toggle source
# File lib/grape/validations.rb, line 159 def use(*names) named_params = @api.settings[:named_params] || {} options = names.last.is_a?(Hash) ? names.pop : {} names.each do |name| params_block = named_params.fetch(name) do raise "Params :#{name} not found!" end instance_exec(options, ¶ms_block) end end
Protected Instance Methods
push_declared_params(attrs)
click to toggle source
# File lib/grape/validations.rb, line 183 def push_declared_params(attrs) @declared_params.concat attrs end
Private Instance Methods
configure_declared_params()
click to toggle source
Pushes declared params to parent or settings
# File lib/grape/validations.rb, line 222 def configure_declared_params if @parent @parent.push_declared_params [element => @declared_params] else @api.settings.peek[:declared_params] ||= [] @api.settings[:declared_params].concat @declared_params end end
new_scope(attrs, optional = false, &block)
click to toggle source
# File lib/grape/validations.rb, line 215 def new_scope(attrs, optional = false, &block) opts = attrs[1] || { type: Array } raise ArgumentError unless opts.keys.to_set.subset? [:type].to_set ParamsScope.new(api: @api, element: attrs.first, parent: self, optional: optional, type: opts[:type], &block) end
require_required_and_optional_fields(context, opts)
click to toggle source
# File lib/grape/validations.rb, line 189 def require_required_and_optional_fields(context, opts) if context == :all optional_fields = Array(opts[:except]) required_fields = opts[:using].keys - optional_fields else # context == :none required_fields = Array(opts[:except]) optional_fields = opts[:using].keys - required_fields end required_fields.each do |field| field_opts = opts[:using][field] raise ArgumentError, "required field not exist: #{field}" unless field_opts requires(field, field_opts) end optional_fields.each do |field| field_opts = opts[:using][field] optional(field, field_opts) if field_opts end end
validate(type, options, attrs, doc_attrs)
click to toggle source
# File lib/grape/validations.rb, line 285 def validate(type, options, attrs, doc_attrs) validator_class = Validations.validators[type.to_s] if validator_class (@api.settings.peek[:validations] ||= []) << validator_class.new(attrs, options, doc_attrs[:required], self) else raise Grape::Exceptions::UnknownValidator.new(type) end end
validate_attributes(attrs, opts, &block)
click to toggle source
# File lib/grape/validations.rb, line 208 def validate_attributes(attrs, opts, &block) validations = { presence: true } validations.merge!(opts) if opts validations[:type] ||= Array if block validates(attrs, validations) end
validates(attrs, validations)
click to toggle source
# File lib/grape/validations.rb, line 231 def validates(attrs, validations) doc_attrs = { required: validations.keys.include?(:presence) } # special case (type = coerce) validations[:coerce] = validations.delete(:type) if validations.key?(:type) coerce_type = validations[:coerce] doc_attrs[:type] = coerce_type.to_s if coerce_type desc = validations.delete(:desc) doc_attrs[:desc] = desc if desc default = validations[:default] doc_attrs[:default] = default if default values = validations[:values] doc_attrs[:values] = values if values values = (values.is_a?(Proc) ? values.call : values) # default value should be present in values array, if both exist if default && values && !values.include?(default) raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :values, values) end # type should be compatible with values array, if both exist if coerce_type && values && values.any? { |v| !v.kind_of?(coerce_type) } raise Grape::Exceptions::IncompatibleOptionValues.new(:type, coerce_type, :values, values) end doc_attrs[:documentation] = validations.delete(:documentation) if validations.key?(:documentation) full_attrs = attrs.collect { |name| { name: name, full_name: full_name(name) } } @api.document_attribute(full_attrs, doc_attrs) # Validate for presence before any other validators if validations.key?(:presence) && validations[:presence] validate('presence', validations[:presence], attrs, doc_attrs) validations.delete(:presence) end # Before we run the rest of the validators, lets handle # whatever coercion so that we are working with correctly # type casted values if validations.key? :coerce validate('coerce', validations[:coerce], attrs, doc_attrs) validations.delete(:coerce) end validations.each do |type, options| validate(type, options, attrs, doc_attrs) end end