module Sequel::Plugins::ValidationHelpers::InstanceMethods

Public Instance Methods

validates_exact_length(exact, atts, opts=OPTS) click to toggle source

Check that the attribute values are the given exact length.

    # File lib/sequel/plugins/validation_helpers.rb
 99 def validates_exact_length(exact, atts, opts=OPTS)
100   validatable_attributes_for_type(:exact_length, atts, opts){|a,v,m| validation_error_message(m, exact) if v.nil? || v.length != exact}
101 end
validates_format(with, atts, opts=OPTS) click to toggle source

Check the string representation of the attribute value(s) against the regular expression with.

    # File lib/sequel/plugins/validation_helpers.rb
104 def validates_format(with, atts, opts=OPTS)
105   validatable_attributes_for_type(:format, atts, opts){|a,v,m| validation_error_message(m, with) unless v.to_s =~ with}
106 end
validates_includes(set, atts, opts=OPTS) click to toggle source

Check attribute value(s) is included in the given set.

    # File lib/sequel/plugins/validation_helpers.rb
109 def validates_includes(set, atts, opts=OPTS)
110   validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.public_send(set.respond_to?(:cover?) ? :cover? : :include?, v)}
111 end
validates_integer(atts, opts=OPTS) click to toggle source

Check attribute value(s) string representation is a valid integer.

    # File lib/sequel/plugins/validation_helpers.rb
114 def validates_integer(atts, opts=OPTS)
115   validatable_attributes_for_type(:integer, atts, opts) do |a,v,m|
116     begin
117       Kernel.Integer(v.to_s)
118       nil
119     rescue
120       validation_error_message(m)
121     end
122   end
123 end
validates_length_range(range, atts, opts=OPTS) click to toggle source

Check that the attribute values length is in the specified range.

    # File lib/sequel/plugins/validation_helpers.rb
126 def validates_length_range(range, atts, opts=OPTS)
127   validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) if v.nil? || !range.cover?(v.length)}
128 end
validates_max_length(max, atts, opts=OPTS) click to toggle source

Check that the attribute values are not longer than the given max length.

Accepts a :nil_message option that is the error message to use when the value is nil instead of being too long.

    # File lib/sequel/plugins/validation_helpers.rb
134 def validates_max_length(max, atts, opts=OPTS)
135   validatable_attributes_for_type(:max_length, atts, opts) do |a,v,m|
136     if v.nil?
137       validation_error_message(opts[:nil_message] || default_validation_helpers_options(:max_length)[:nil_message])
138     elsif v.length > max
139       validation_error_message(m, max)
140     end
141   end
142 end
validates_min_length(min, atts, opts=OPTS) click to toggle source

Check that the attribute values are not shorter than the given min length.

    # File lib/sequel/plugins/validation_helpers.rb
145 def validates_min_length(min, atts, opts=OPTS)
146   validatable_attributes_for_type(:min_length, atts, opts){|a,v,m| validation_error_message(m, min) if v.nil? || v.length < min}
147 end
validates_no_null_byte(atts, opts=OPTS) click to toggle source

Check attribute value(s) does not contain a null (“0”, ASCII NUL) byte.

    # File lib/sequel/plugins/validation_helpers.rb
155 def validates_no_null_byte(atts, opts=OPTS)
156   validatable_attributes_for_type(:no_null_byte, atts, opts){|a,v,m| validation_error_message(m) if String === v && v.include?("\0")}
157 end
validates_not_null(atts, opts=OPTS) click to toggle source

Check attribute value(s) are not NULL/nil.

    # File lib/sequel/plugins/validation_helpers.rb
150 def validates_not_null(atts, opts=OPTS)
151   validatable_attributes_for_type(:not_null, atts, opts){|a,v,m| validation_error_message(m) if v.nil?}
152 end
validates_numeric(atts, opts=OPTS) click to toggle source

Check attribute value(s) string representation is a valid float.

    # File lib/sequel/plugins/validation_helpers.rb
160 def validates_numeric(atts, opts=OPTS)
161   validatable_attributes_for_type(:numeric, atts, opts) do |a,v,m|
162     begin
163       Kernel.Float(v.to_s)
164       nil
165     rescue
166       validation_error_message(m)
167     end
168   end
169 end
validates_operator(operator, rhs, atts, opts=OPTS) click to toggle source

Check attribute value(s) against a specified value and operation, e.g. validates_operator(:>, 3, :value) validates that value > 3.

    # File lib/sequel/plugins/validation_helpers.rb
173 def validates_operator(operator, rhs, atts, opts=OPTS)
174   validatable_attributes_for_type(:operator, atts, opts){|a,v,m| validation_error_message(m, operator, rhs) if v.nil? || !v.public_send(operator, rhs)}
175 end
validates_presence(atts, opts=OPTS) click to toggle source

Check attribute value(s) is not considered blank by the database, but allow false values.

    # File lib/sequel/plugins/validation_helpers.rb
200 def validates_presence(atts, opts=OPTS)
201   validatable_attributes_for_type(:presence, atts, opts){|a,v,m| validation_error_message(m) if model.db.send(:blank_object?, v) && v != false}
202 end
validates_schema_types(atts=keys, opts=OPTS) click to toggle source

Validates for all of the model columns (or just the given columns) that the column value is an instance of the expected class based on the column's schema type.

    # File lib/sequel/plugins/validation_helpers.rb
180 def validates_schema_types(atts=keys, opts=OPTS)
181   Array(atts).each do |k|
182     if type = schema_type_class(k)
183       validates_type(type, k, {:allow_nil=>true}.merge!(opts))
184     end
185   end
186 end
validates_type(klass, atts, opts=OPTS) click to toggle source

Check if value is an instance of a class. If klass is an array, the value must be an instance of one of the classes in the array.

    # File lib/sequel/plugins/validation_helpers.rb
190 def validates_type(klass, atts, opts=OPTS)
191   klass = klass.to_s.constantize if klass.is_a?(String) || klass.is_a?(Symbol)
192   validatable_attributes_for_type(:type, atts, opts) do |a,v,m|
193     if klass.is_a?(Array) ? !klass.any?{|kls| v.is_a?(kls)} : !v.is_a?(klass)
194       validation_error_message(m, klass)
195     end
196   end
197 end
validates_unique(*atts) { |ds| ... } click to toggle source

Checks that there are no duplicate values in the database for the given attributes. 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_unique([:column1, :column2])

validates the grouping of column1 and column2 while

validates_unique(:column1, :column2)

validates them separately.

You can pass a block, which is yielded the dataset in which the columns must be unique. So if you are doing a soft delete of records, in which the name must be unique, but only for active records:

validates_unique(:name){|ds| ds.where(:active)}

You should also add a unique index in the database, as this suffers from a fairly obvious race condition.

This validation does not respect the :allow_* options that the other validations accept, since it can deal with a grouping of multiple attributes.

Possible Options:

:dataset

The base dataset to use for the unique query, defaults to the model's dataset.

:message

The message to use (default: 'is already taken')

:only_if_modified

Only check the uniqueness if the object is new or one of the columns has been modified, true by default.

:where

A callable object where call takes three arguments, a dataset, the current object, and an array of columns, and should return a modified dataset that is filtered to include only rows with the same values as the current object for each column in the array.

If you want to do a case insensitive uniqueness validation on a database that is case sensitive by default, you can use:

validates_unique :column, where:(lambda do |ds, obj, cols|
  ds.where(cols.map do |c|
    v = obj.public_send(c)
    v = v.downcase if v
    [Sequel.function(:lower, c), v]
  end)
end)
    # File lib/sequel/plugins/validation_helpers.rb
248 def validates_unique(*atts)
249   opts = default_validation_helpers_options(:unique)
250   if atts.last.is_a?(Hash)
251     opts = opts.merge(atts.pop)
252   end
253   message = validation_error_message(opts[:message])
254   from_values = opts[:from] == :values
255   where = opts[:where]
256   atts.each do |a|
257     arr = Array(a)
258     next if arr.any?{|x| errors.on(x)}
259     cc = changed_columns
260     next if opts.fetch(:only_if_modified, true) && !new? && !arr.any?{|x| cc.include?(x)}
261     ds = opts[:dataset] || model.dataset
262     ds = if where
263       where.call(ds, self, arr)
264     else
265       vals = arr.map{|x| from_values ? values[x] : get_column_value(x)}
266       next if vals.any?(&:nil?)
267       ds.where(arr.zip(vals))
268     end
269     ds = yield(ds) if defined?(yield)
270     unless new?
271       h = ds.joined_dataset? ? qualified_pk_hash : pk_hash
272       ds = ds.exclude(h)
273     end
274     errors.add(a, message) unless ds.count == 0
275   end
276 end

Private Instance Methods

default_validation_helpers_options(type) click to toggle source

The default options hash for the given type of validation. Can be overridden on a per-model basis for different per model defaults. The hash return must include a :message option that is either a proc or string.

    # File lib/sequel/plugins/validation_helpers.rb
284 def default_validation_helpers_options(type)
285   DEFAULT_OPTIONS[type]
286 end
validatable_attributes(atts, opts) { |a, v, m| ... } click to toggle source

Skip validating any attribute that matches one of the allow_* options, or already has an error if the skip_invalid option is given.

Otherwise, yield the attribute, value, and passed option :message to the block. If the block returns anything except nil or false, add it as an error message for that attributes.

    # File lib/sequel/plugins/validation_helpers.rb
294 def validatable_attributes(atts, opts)
295   am, an, ab, m, si = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message, :skip_invalid)
296   from_values = opts[:from] == :values
297   Array(atts).each do |a|
298     next if si && errors.on(a)
299     next if am && !values.has_key?(a)
300     v = from_values ? values[a] : get_column_value(a)
301     next if an && v.nil?
302     next if ab && model.db.send(:blank_object?, v)
303     if message = yield(a, v, m)
304       errors.add(a, message)
305     end
306   end
307 end
validatable_attributes_for_type(type, atts, opts, &block) click to toggle source

Merge the given options with the default options for the given type and call validatable_attributes with the merged options.

    # File lib/sequel/plugins/validation_helpers.rb
311 def validatable_attributes_for_type(type, atts, opts, &block)
312   validatable_attributes(atts, default_validation_helpers_options(type).merge(opts), &block)
313 end
validation_error_message(message, *args) click to toggle source

The validation error message to use, as a string. If message is a Proc, call it with the args. Otherwise, assume it is a string and return it.

    # File lib/sequel/plugins/validation_helpers.rb
318 def validation_error_message(message, *args)
319   message.is_a?(Proc) ? message.call(*args) : message
320 end