Returns true if validations are defined.
# File lib/sequel/plugins/validation_class_methods.rb, line 57 57: def has_validations? 58: !validations.empty? 59: end
Setup the validations and validation_reflections hash in the subclass.
# File lib/sequel/plugins/validation_class_methods.rb, line 62 62: def inherited(subclass) 63: vr = @validation_reflections 64: subclass.class_eval do 65: @validation_mutex = Mutex.new 66: @validations = {} 67: h = {} 68: vr.each{|k,v| h[k] = v.dup} 69: @validation_reflections = h 70: end 71: super 72: end
Instructs the model to skip validations defined in superclasses
# File lib/sequel/plugins/validation_class_methods.rb, line 75 75: def skip_superclass_validations 76: @skip_superclass_validations = true 77: end
Instructs the model to skip validations defined in superclasses
# File lib/sequel/plugins/validation_class_methods.rb, line 80 80: def skip_superclass_validations? 81: defined?(@skip_superclass_validations) && @skip_superclass_validations 82: end
Validates the given instance.
# File lib/sequel/plugins/validation_class_methods.rb, line 104 104: def validate(o) 105: superclass.validate(o) if superclass.respond_to?(:validate) && !skip_superclass_validations? 106: validations.each do |att, procs| 107: v = case att 108: when Array 109: att.collect{|a| o.send(a)} 110: else 111: o.send(att) 112: end 113: procs.each {|tag, p| p.call(o, att, v)} 114: end 115: end
Defines validations by converting a longhand block into a series of shorthand definitions. For example:
class MyClass < Sequel::Model validates do length_of :name, :minimum => 6 length_of :password, :minimum => 8 end end
is equivalent to:
class MyClass < Sequel::Model validates_length_of :name, :minimum => 6 validates_length_of :password, :minimum => 8 end
# File lib/sequel/plugins/validation_class_methods.rb, line 99 99: def validates(&block) 100: Generator.new(self, &block) 101: end
Validates acceptance of an attribute. Just checks that the value is equal to the :accept option. This method is unique in that :allow_nil is assumed to be true instead of false.
Possible Options:
:accept - The value required for the object to be valid (default: ‘1’)
:message - The message to use (default: ‘is not accepted’)
# File lib/sequel/plugins/validation_class_methods.rb, line 124 124: def validates_acceptance_of(*atts) 125: opts = { 126: :message => 'is not accepted', 127: :allow_nil => true, 128: :accept => '1', 129: :tag => :acceptance, 130: }.merge!(extract_options!(atts)) 131: reflect_validation(:acceptance, opts, atts) 132: atts << opts 133: validates_each(*atts) do |o, a, v| 134: o.errors.add(a, opts[:message]) unless v == opts[:accept] 135: end 136: end
Validates confirmation of an attribute. Checks that the object has a _confirmation value matching the current value. For example:
validates_confirmation_of :blah
Just makes sure that object.blah = object.blah_confirmation. Often used for passwords or email addresses on web forms.
Possible Options:
:message - The message to use (default: ‘is not confirmed’)
# File lib/sequel/plugins/validation_class_methods.rb, line 148 148: def validates_confirmation_of(*atts) 149: opts = { 150: :message => 'is not confirmed', 151: :tag => :confirmation, 152: }.merge!(extract_options!(atts)) 153: reflect_validation(:confirmation, opts, atts) 154: atts << opts 155: validates_each(*atts) do |o, a, v| 156: o.errors.add(a, opts[:message]) unless v == o.send(:"#{a}_confirmation") 157: end 158: end
Adds a validation for each of the given attributes using the supplied block. The block must accept three arguments: instance, attribute and value, e.g.:
validates_each :name, :password do |object, attribute, value| object.errors.add(attribute, 'is not nice') unless value.nice? end
Possible Options:
:allow_blank - Whether to skip the validation if the value is blank.
:allow_missing - Whether to skip the validation if the attribute isn’t a key in the values hash. This is different from allow_nil, because Sequel only sends the attributes in the values when doing an insert or update. If the attribute is not present, Sequel doesn’t specify it, so the database will use the table’s default value. This is different from having an attribute in values with a value of nil, which Sequel will send as NULL. If your database table has a non NULL default, this may be a good option to use. You don’t want to use allow_nil, because if the attribute is in values but has a value nil, Sequel will attempt to insert a NULL value into the database, instead of using the database’s default.
:allow_nil - Whether to skip the validation if the value is nil.
:if - A symbol (indicating an instance_method) or proc (which is instance_evaled) skipping this validation if it returns nil or false.
:tag - The tag to use for this validation.
# File lib/sequel/plugins/validation_class_methods.rb, line 183 183: def validates_each(*atts, &block) 184: opts = extract_options!(atts) 185: blk = if (i = opts[:if]) || (am = opts[:allow_missing]) || (an = opts[:allow_nil]) || (ab = opts[:allow_blank]) 186: proc do |o,a,v| 187: next if i && !validation_if_proc(o, i) 188: next if an && Array(v).all?{|x| x.nil?} 189: next if ab && Array(v).all?{|x| x.blank?} 190: next if am && Array(a).all?{|x| !o.values.has_key?(x)} 191: block.call(o,a,v) 192: end 193: else 194: block 195: end 196: tag = opts[:tag] 197: atts.each do |a| 198: a_vals = @validation_mutex.synchronize{validations[a] ||= []} 199: if tag && (old = a_vals.find{|x| x[0] == tag}) 200: old[1] = blk 201: else 202: a_vals << [tag, blk] 203: end 204: end 205: end
Validates the format of an attribute, checking the string representation of the value against the regular expression provided by the :with option.
Possible Options:
:message - The message to use (default: ‘is invalid’)
:with - The regular expression to validate the value with (required).
# File lib/sequel/plugins/validation_class_methods.rb, line 213 213: def validates_format_of(*atts) 214: opts = { 215: :message => 'is invalid', 216: :tag => :format, 217: }.merge!(extract_options!(atts)) 218: 219: unless opts[:with].is_a?(Regexp) 220: raise ArgumentError, "A regular expression must be supplied as the :with option of the options hash" 221: end 222: 223: reflect_validation(:format, opts, atts) 224: atts << opts 225: validates_each(*atts) do |o, a, v| 226: o.errors.add(a, opts[:message]) unless v.to_s =~ opts[:with] 227: end 228: end
Validates that an attribute is within a specified range or set of values.
Possible Options:
:in - An array or range of values to check for validity (required)
:message - The message to use (default: ‘is not in range or set:
# File lib/sequel/plugins/validation_class_methods.rb, line 346 346: def validates_inclusion_of(*atts) 347: opts = extract_options!(atts) 348: n = opts[:in] 349: unless n && (n.respond_to?(:cover?) || n.respond_to?(:include?)) 350: raise ArgumentError, "The :in parameter is required, and must respond to cover? or include?" 351: end 352: opts[:message] ||= "is not in range or set: #{n.inspect}" 353: reflect_validation(:inclusion, opts, atts) 354: atts << opts 355: validates_each(*atts) do |o, a, v| 356: o.errors.add(a, opts[:message]) unless n.send(n.respond_to?(:cover?) ? :cover? : :include?, v) 357: end 358: end
Validates the length of an attribute.
Possible Options:
:is - The exact size required for the value to be valid (no default)
:maximum - The maximum size allowed for the value (no default)
:message - The message to use (no default, overrides :nil_message, :too_long, :too_short, and :wrong_length options if present)
:minimum - The minimum size allowed for the value (no default)
:nil_message - The message to use use if :maximum option is used and the value is nil (default: ‘is not present’)
:too_long - The message to use use if it the value is too long (default: ‘is too long’)
:too_short - The message to use use if it the value is too short (default: ‘is too short’)
:within - The array/range that must include the size of the value for it to be valid (no default)
:wrong_length - The message to use use if it the value is not valid (default: ‘is the wrong length’)
# File lib/sequel/plugins/validation_class_methods.rb, line 243 243: def validates_length_of(*atts) 244: opts = { 245: :nil_message => 'is not present', 246: :too_long => 'is too long', 247: :too_short => 'is too short', 248: :wrong_length => 'is the wrong length' 249: }.merge!(extract_options!(atts)) 250: 251: opts[:tag] ||= ([:length] + [:maximum, :minimum, :is, :within].reject{|x| !opts.include?(x)}).join('-').to_sym 252: reflect_validation(:length, opts, atts) 253: atts << opts 254: validates_each(*atts) do |o, a, v| 255: if m = opts[:maximum] 256: o.errors.add(a, opts[:message] || (v ? opts[:too_long] : opts[:nil_message])) unless v && v.size <= m 257: end 258: if m = opts[:minimum] 259: o.errors.add(a, opts[:message] || opts[:too_short]) unless v && v.size >= m 260: end 261: if i = opts[:is] 262: o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && v.size == i 263: end 264: if w = opts[:within] 265: o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && w.send(w.respond_to?(:cover?) ? :cover? : :include?, v.size) 266: end 267: end 268: end
Validates whether an attribute is not a string. This is generally useful in conjunction with raise_on_typecast_failure = false, where you are passing in string values for non-string attributes (such as numbers and dates). If typecasting fails (invalid number or date), the value of the attribute will be a string in an invalid format, and if typecasting succeeds, the value will not be a string.
Possible Options:
:message - The message to use (default: ‘is a string’ or ‘is not a valid (integer|datetime|etc.)’ if the type is known)
# File lib/sequel/plugins/validation_class_methods.rb, line 279 279: def validates_not_string(*atts) 280: opts = { 281: :tag => :not_string, 282: }.merge!(extract_options!(atts)) 283: reflect_validation(:not_string, opts, atts) 284: atts << opts 285: validates_each(*atts) do |o, a, v| 286: if v.is_a?(String) 287: unless message = opts[:message] 288: message = if sch = o.db_schema[a] and typ = sch[:type] 289: "is not a valid #{typ}" 290: else 291: "is a string" 292: end 293: end 294: o.errors.add(a, message) 295: end 296: end 297: end
Validates whether an attribute is a number.
Possible Options:
:message - The message to use (default: ‘is not a number’)
:only_integer - Whether only integers are valid values (default: false)
# File lib/sequel/plugins/validation_class_methods.rb, line 304 304: def validates_numericality_of(*atts) 305: opts = { 306: :message => 'is not a number', 307: :tag => :numericality, 308: }.merge!(extract_options!(atts)) 309: reflect_validation(:numericality, opts, atts) 310: atts << opts 311: validates_each(*atts) do |o, a, v| 312: begin 313: if opts[:only_integer] 314: Kernel.Integer(v.to_s) 315: else 316: Kernel.Float(v.to_s) 317: end 318: rescue 319: o.errors.add(a, opts[:message]) 320: end 321: end 322: end
Validates the presence of an attribute. Requires the value not be blank, with false considered present instead of absent.
Possible Options:
:message - The message to use (default: ‘is not present’)
# File lib/sequel/plugins/validation_class_methods.rb, line 329 329: def validates_presence_of(*atts) 330: opts = { 331: :message => 'is not present', 332: :tag => :presence, 333: }.merge!(extract_options!(atts)) 334: reflect_validation(:presence, opts, atts) 335: atts << opts 336: validates_each(*atts) do |o, a, v| 337: o.errors.add(a, opts[:message]) if v.blank? && v != false 338: end 339: end
Validates only if the fields in the model (specified by atts) are unique in the database. Pass an array of fields instead of multiple fields to specify that the combination of fields must be unique, instead of that each field should have a unique value.
This means that the code:
validates_uniqueness_of([:column1, :column2])
validates the grouping of column1 and column2 while
validates_uniqueness_of(:column1, :column2)
validates them separately.
You should also add a unique index in the database, as this suffers from a fairly obvious race condition.
Possible Options:
:message - The message to use (default: ‘is already taken’)
# File lib/sequel/plugins/validation_class_methods.rb, line 376 376: def validates_uniqueness_of(*atts) 377: opts = { 378: :message => 'is already taken', 379: :tag => :uniqueness, 380: }.merge!(extract_options!(atts)) 381: 382: reflect_validation(:uniqueness, opts, atts) 383: atts << opts 384: validates_each(*atts) do |o, a, v| 385: error_field = a 386: a = Array(a) 387: v = Array(v) 388: ds = o.class.filter(a.zip(v)) 389: num_dups = ds.count 390: allow = if num_dups == 0 391: # No unique value in the database 392: true 393: elsif num_dups > 1 394: # Multiple "unique" values in the database!! 395: # Someone didn't add a unique index 396: false 397: elsif o.new? 398: # New record, but unique value already exists in the database 399: false 400: elsif ds.first === o 401: # Unique value exists in database, but for the same record, so the update won't cause a duplicate record 402: true 403: else 404: false 405: end 406: o.errors.add(error_field, opts[:message]) unless allow 407: end 408: end
Removes and returns the last member of the array if it is a hash. Otherwise, an empty hash is returned This method is useful when writing methods that take an options hash as the last parameter.
# File lib/sequel/plugins/validation_class_methods.rb, line 415 415: def extract_options!(array) 416: array.last.is_a?(Hash) ? array.pop : {} 417: end
Add the validation reflection to the class’s validations.
# File lib/sequel/plugins/validation_class_methods.rb, line 420 420: def reflect_validation(type, opts, atts) 421: atts.each do |att| 422: (validation_reflections[att] ||= []) << [type, opts] 423: end 424: end
Handle the :if option for validations
# File lib/sequel/plugins/validation_class_methods.rb, line 427 427: def validation_if_proc(o, i) 428: case i 429: when Symbol then o.send(i) 430: when Proc then o.instance_eval(&i) 431: when nil then true 432: else raise(::Sequel::Error, "invalid value for :if validation option") 433: end 434: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.