module Sack::Database::Model::Validation::ClassMethods
Class Methods: Collection of methods to be injected into anything that includes this module.
Public Instance Methods
is_uniq?(db, data, name, val, scope)
click to toggle source
Is Unique: Verifies the unicity of a given field (name) value (val) on an entity (data), possibly within a given scope. @param [Database] db Database
instance (Sack::Database
) @param [Hash] data Entity data @param [Symbol] name Field name @param [Object] val Field value @param [Object] scope Either True (if absolute - no scope) or an Array of field names defining the scope
# File lib/sack/database/model/validation.rb, line 121 def is_uniq? db, data, name, val, scope # Fetch all other rows with field [name] equal to [val] others = db.fetch_by table_name, name, val others.reject! { |o| o[:id] == data[:id] } if data[:id] # If scopeless (absolutely unique), check empty set and return return others.empty? unless scope.is_a? Array # Check Unique throughout Scope scope.each { |f| others.reject! { |o| o[f] != data[f] } } others.empty? end
is_valid?(db, data, errors = [])
click to toggle source
Is Valid: Verifies the validity of a given entity (data) against this Model
. @param [Database] db Database
instance (Sack::Database
) @param [Hash] data Entity data
# File lib/sack/database/model/validation.rb, line 47 def is_valid? db, data, errors = [] # Run through Model's Field Schema fields.inject(true) do |a, e| # Acquire Field Info name = e[0] info = e[1] ftype = info[:ftype] rules = info[:rules] val = data[name] # Handle Required if rules[:required] r = val.try :is_a?, FTYPES_CLASSES[ftype.first] a &&= r errors << "Required field [#{name}] is missing" unless r end # Handle Unique if rules[:unique] r = is_uniq? db, data, name, val, rules[:unique] a &&= r errors << "Field [#{name}] has non-unique value [#{val}]#{rules[:unique].is_a?(Array) ? " in scope [#{rules[:unique].join ', '}]" : ''}" unless r end # Handle Set Length if rules[:length] r = val.try(:length).try :==, rules[:length] a &&= r errors << "Field [#{name}] has invalid length (#{val.try(:length)} / #{rules[:length]})" unless r end # Handle Minimum Length if rules[:min_length] r = val.try(:length).try :>=, rules[:min_length] a &&= r errors << "Field [#{name}] has invalid length (#{val.try(:length)} / Min: #{rules[:min_length]})" unless r end # Handle Maximum Length if rules[:max_length] r = val.try(:length).try :<=, rules[:max_length] a &&= r errors << "Field [#{name}] has invalid length (#{val.try(:length)} / Max: #{rules[:max_length]})" unless r end # Handle Regex if rules[:regex] r = rules[:regex] =~ val a &&= r errors << "Field [#{name}] doesn't match allowed pattern (#{rules[:regex].inspect})" unless r end # Handle Custom if rules[:validate] size = errors.size r = send rules[:validate], db, data, name, val, rules, errors a &&= r errors << "Field [#{name}] is invalid" unless r || (size != errors.size) end # Don't leak shit !!a end end