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
101 def validates_exact_length(exact, atts, opts=OPTS)
102   validatable_attributes_for_type(:exact_length, atts, opts){|a,v,m| validation_error_message(m, exact) if v.nil? || v.length != exact}
103 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
106 def validates_format(with, atts, opts=OPTS)
107   validatable_attributes_for_type(:format, atts, opts){|a,v,m| validation_error_message(m, with) unless v.to_s =~ with}
108 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
111 def validates_includes(set, atts, opts=OPTS)
112   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)}
113 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
116 def validates_integer(atts, opts=OPTS)
117   validatable_attributes_for_type(:integer, atts, opts) do |a,v,m|
118     begin
119       Kernel.Integer(v.to_s)
120       nil
121     rescue
122       validation_error_message(m)
123     end
124   end
125 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
128 def validates_length_range(range, atts, opts=OPTS)
129   validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) if v.nil? || !range.cover?(v.length)}
130 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
136 def validates_max_length(max, atts, opts=OPTS)
137   validatable_attributes_for_type(:max_length, atts, opts) do |a,v,m|
138     if v.nil?
139       validation_error_message(opts[:nil_message] || default_validation_helpers_options(:max_length)[:nil_message])
140     elsif v.length > max
141       validation_error_message(m, max)
142     end
143   end
144 end
validates_max_value(max, atts, opts=OPTS) click to toggle source

Check that the attribute values are not greater that the given maximum value. Does not perform validation if attribute value is nil. You should only call this if you have checked the attribute value has the expected type.

    # File lib/sequel/plugins/validation_helpers.rb
149 def validates_max_value(max, atts, opts=OPTS)
150   validatable_attributes_for_type(:max_value, atts, opts) do |a,v,m|
151     validation_error_message(m, max) if !v.nil? && v > max
152   end
153 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
156 def validates_min_length(min, atts, opts=OPTS)
157   validatable_attributes_for_type(:min_length, atts, opts){|a,v,m| validation_error_message(m, min) if v.nil? || v.length < min}
158 end
validates_min_value(min, atts, opts=OPTS) click to toggle source

Check that the attribute values are not less that the given minimum value. Does not perform validation if attribute value is nil. You should only call this if you have checked the attribute value has the expected type.

    # File lib/sequel/plugins/validation_helpers.rb
163 def validates_min_value(min, atts, opts=OPTS)
164   validatable_attributes_for_type(:min_value, atts, opts) do |a,v,m|
165     validation_error_message(m, min) if !v.nil? && v < min
166   end
167 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
175 def validates_no_null_byte(atts, opts=OPTS)
176   validatable_attributes_for_type(:no_null_byte, atts, opts){|a,v,m| validation_error_message(m) if String === v && v.include?("\0")}
177 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
170 def validates_not_null(atts, opts=OPTS)
171   validatable_attributes_for_type(:not_null, atts, opts){|a,v,m| validation_error_message(m) if v.nil?}
172 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
180 def validates_numeric(atts, opts=OPTS)
181   validatable_attributes_for_type(:numeric, atts, opts) do |a,v,m|
182     begin
183       Kernel.Float(v.to_s)
184       nil
185     rescue
186       validation_error_message(m)
187     end
188   end
189 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
193 def validates_operator(operator, rhs, atts, opts=OPTS)
194   validatable_attributes_for_type(:operator, atts, opts){|a,v,m| validation_error_message(m, operator, rhs) if v.nil? || !v.public_send(operator, rhs)}
195 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
220 def validates_presence(atts, opts=OPTS)
221   validatable_attributes_for_type(:presence, atts, opts){|a,v,m| validation_error_message(m) if model.db.send(:blank_object?, v) && v != false}
222 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
200 def validates_schema_types(atts=keys, opts=OPTS)
201   Array(atts).each do |k|
202     if type = schema_type_class(k)
203       validates_type(type, k, {:allow_nil=>true}.merge!(opts))
204     end
205   end
206 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
210 def validates_type(klass, atts, opts=OPTS)
211   klass = klass.to_s.constantize if klass.is_a?(String) || klass.is_a?(Symbol)
212   validatable_attributes_for_type(:type, atts, opts) do |a,v,m|
213     if klass.is_a?(Array) ? !klass.any?{|kls| v.is_a?(kls)} : !v.is_a?(klass)
214       validation_error_message(m, klass)
215     end
216   end
217 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
268 def validates_unique(*atts)
269   opts = default_validation_helpers_options(:unique)
270   if atts.last.is_a?(Hash)
271     opts = opts.merge(atts.pop)
272   end
273   message = validation_error_message(opts[:message])
274   from_values = opts[:from] == :values
275   where = opts[:where]
276   atts.each do |a|
277     arr = Array(a)
278     next if arr.any?{|x| errors.on(x)}
279     cc = changed_columns
280     next if opts.fetch(:only_if_modified, true) && !new? && !arr.any?{|x| cc.include?(x)}
281     ds = opts[:dataset] || model.dataset
282     ds = if where
283       where.call(ds, self, arr)
284     else
285       vals = arr.map{|x| from_values ? values[x] : get_column_value(x)}
286       next if vals.any?(&:nil?)
287       ds.where(arr.zip(vals))
288     end
289     ds = yield(ds) if defined?(yield)
290     unless new?
291       h = ds.joined_dataset? ? qualified_pk_hash : pk_hash
292       ds = ds.exclude(h)
293     end
294     errors.add(a, message) unless ds.count == 0
295   end
296 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
304 def default_validation_helpers_options(type)
305   DEFAULT_OPTIONS[type]
306 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
314 def validatable_attributes(atts, opts)
315   am, an, ab, m, si = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message, :skip_invalid)
316   from_values = opts[:from] == :values
317   Array(atts).each do |a|
318     next if si && errors.on(a)
319     next if am && !values.has_key?(a)
320     v = from_values ? values[a] : get_column_value(a)
321     next if an && v.nil?
322     next if ab && model.db.send(:blank_object?, v)
323     if message = yield(a, v, m)
324       errors.add(a, message)
325     end
326   end
327 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
331 def validatable_attributes_for_type(type, atts, opts, &block)
332   validatable_attributes(atts, default_validation_helpers_options(type).merge(opts), &block)
333 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
338 def validation_error_message(message, *args)
339   message.is_a?(Proc) ? message.call(*args) : message
340 end