require 'active_support/inflector' require 'fanforce/errors' require 'fanforce/utils' module Fanforce::Validations include Fanforce::Utils extend Fanforce::Validations def self.included(base) base.extend(self) end def extract_validation_params(opts) return opts.delete(:params) if is_present?(opts[:params]) return self.params if self.respond_to?(:params) Fanforce.env[:request_params] || {} end def parse_validation_field_name(field, i, opts, params) name = opts[:fields][i] if is_present?(opts[:fields]) name = field if is_blank?(name) and field.is_a?(Symbol) name = :unknown if is_blank?(name) name.to_sym end def validates_presence_of_all(*args) opts = extract_options!(args) params = extract_validation_params(opts) fields_to_validate = args.is_a?(Array) ? args : [args] invalid_fields = [] fields_to_validate.each_with_index do |field_to_validate, i| if !(field_to_validate.is_a?(Symbol) ? is_present?(params[field_to_validate]) : is_present?(field_to_validate)) invalid_fields << parse_validation_field_name(field_to_validate, i, opts, params) end end return true if invalid_fields.size == 0 errors = invalid_fields.inject([]) {|result, f| result << format_validation_error(opts, f, :missing_field) } raise_validation_errors(opts, errors, Fanforce::Error::BadRequest) end alias :validates_presence_of :validates_presence_of_all def validates_presence_of_any(*args) opts = extract_options!(args) params = extract_validation_params(opts) fields_to_validate = args.is_a?(Array) ? args : [args] invalid_fields = [] fields_to_validate.each_with_index do |field_to_validate, i| if !(field_to_validate.is_a?(Symbol) ? is_present?(params[field_to_validate]) : is_present?(field_to_validate)) invalid_fields << parse_validation_field_name(field_to_validate, i, opts, params) end end return true if invalid_fields.size < fields_to_validate.size errors = [format_validation_error(opts, invalid_fields, :invalid_data)] raise_validation_errors(opts, errors, Fanforce::Error::BadRequest) end def validates_true(*args) opts = extract_options!(args) params = extract_validation_params(opts) bools_to_validate = args.is_a?(Array) ? args : [args] invalid_fields = [] bools_to_validate.each_with_index do |bool_is_true, i| if !bool_is_true invalid_fields << parse_validation_field_name(nil, i, opts, nil) end end return true if invalid_fields.size == 0 errors = invalid_fields.inject([]) {|result, f| result << format_validation_error(opts, f, :invalid_data) } raise_validation_errors(opts, errors, Fanforce::Error::RequestFailed) end def validates_format_of_external_id(*args) opts = extract_options!(args).merge(:field => :_external_id) params = extract_validation_params(opts) _external_id = args if is_present?(_external_id) and !_external_id.is_a?(String) opts[:message] = "id must be a string but was a #{_external_id.class.name}" elsif _external_id.include('/') opts[:message] = 'id cannot contain forward slashes (/)' else return true end error = format_validation_error(opts, :_external_id, :invalid_data) raise_validation_errors(opts, [error], Fanforce::Error::RequestFailed) end def format_validation_error(opts, fields, default_error_code=nil) error = { resource: is_present?(opts[:resource]) ? opts[:resource] : (self.class==Class ? self.name.demodulize.tableize.singularize : self.class.name.demodulize.tableize.singularize), code: is_present?(opts[:code]) ? opts[:code] : default_error_code, message: opts[:message] } fields.is_a?(Array) ? error.update(fields: fields) : error.update(field: fields) end def raise_validation_errors(opts, errors, default_error_class) raise (opts[:error_class] || default_error_class).new(*errors) end def extract_options!(args) if args.last.is_a?(::Hash) opts = args.pop.symbolize_keys if is_present?(opts[:field]) and opts[:fields].is_a?(Array) opts[:fields] << opts.delete(:field) elsif is_present?(opts[:field]) opts[:fields] = [opts.delete(:field)] end return opts elsif args.last.is_a?(::String) {message: args.pop.to_s} else {} end end end