module Sequel::Plugins::ValidationHelpers::InstanceMethods
Public Instance Methods
Check that the attribute values are the given exact length.
# File lib/sequel/plugins/validation_helpers.rb 100 def validates_exact_length(exact, atts, opts=OPTS) 101 validatable_attributes_for_type(:exact_length, atts, opts){|a,v,m| validation_error_message(m, exact) if v.nil? || v.length != exact} 102 end
Check the string representation of the attribute value(s) against the regular expression with.
# File lib/sequel/plugins/validation_helpers.rb 105 def validates_format(with, atts, opts=OPTS) 106 validatable_attributes_for_type(:format, atts, opts){|a,v,m| validation_error_message(m, with) unless v.to_s =~ with} 107 end
Check attribute value(s) is included in the given set.
# File lib/sequel/plugins/validation_helpers.rb 110 def validates_includes(set, atts, opts=OPTS) 111 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)} 112 end
Check attribute value(s) string representation is a valid integer.
# File lib/sequel/plugins/validation_helpers.rb 115 def validates_integer(atts, opts=OPTS) 116 validatable_attributes_for_type(:integer, atts, opts) do |a,v,m| 117 begin 118 Kernel.Integer(v.to_s) 119 nil 120 rescue 121 validation_error_message(m) 122 end 123 end 124 end
Check that the attribute values length is in the specified range.
# File lib/sequel/plugins/validation_helpers.rb 127 def validates_length_range(range, atts, opts=OPTS) 128 validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) if v.nil? || !range.cover?(v.length)} 129 end
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 135 def validates_max_length(max, atts, opts=OPTS) 136 validatable_attributes_for_type(:max_length, atts, opts) do |a,v,m| 137 if v.nil? 138 validation_error_message(opts[:nil_message] || default_validation_helpers_options(:max_length)[:nil_message]) 139 elsif v.length > max 140 validation_error_message(m, max) 141 end 142 end 143 end
Check that the attribute values are not shorter than the given min length.
# File lib/sequel/plugins/validation_helpers.rb 146 def validates_min_length(min, atts, opts=OPTS) 147 validatable_attributes_for_type(:min_length, atts, opts){|a,v,m| validation_error_message(m, min) if v.nil? || v.length < min} 148 end
Check attribute value(s) are not NULL/nil.
# File lib/sequel/plugins/validation_helpers.rb 151 def validates_not_null(atts, opts=OPTS) 152 validatable_attributes_for_type(:not_null, atts, opts){|a,v,m| validation_error_message(m) if v.nil?} 153 end
Check attribute value(s) string representation is a valid float.
# File lib/sequel/plugins/validation_helpers.rb 156 def validates_numeric(atts, opts=OPTS) 157 validatable_attributes_for_type(:numeric, atts, opts) do |a,v,m| 158 begin 159 Kernel.Float(v.to_s) 160 nil 161 rescue 162 validation_error_message(m) 163 end 164 end 165 end
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 169 def validates_operator(operator, rhs, atts, opts=OPTS) 170 validatable_attributes_for_type(:operator, atts, opts){|a,v,m| validation_error_message(m, operator, rhs) if v.nil? || !v.public_send(operator, rhs)} 171 end
Check attribute value(s) is not considered blank by the database, but allow false values.
# File lib/sequel/plugins/validation_helpers.rb 196 def validates_presence(atts, opts=OPTS) 197 validatable_attributes_for_type(:presence, atts, opts){|a,v,m| validation_error_message(m) if model.db.send(:blank_object?, v) && v != false} 198 end
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 176 def validates_schema_types(atts=keys, opts=OPTS) 177 Array(atts).each do |k| 178 if type = schema_type_class(k) 179 validates_type(type, k, {:allow_nil=>true}.merge!(opts)) 180 end 181 end 182 end
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 186 def validates_type(klass, atts, opts=OPTS) 187 klass = klass.to_s.constantize if klass.is_a?(String) || klass.is_a?(Symbol) 188 validatable_attributes_for_type(:type, atts, opts) do |a,v,m| 189 if klass.is_a?(Array) ? !klass.any?{|kls| v.is_a?(kls)} : !v.is_a?(klass) 190 validation_error_message(m, klass) 191 end 192 end 193 end
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 244 def validates_unique(*atts) 245 opts = default_validation_helpers_options(:unique) 246 if atts.last.is_a?(Hash) 247 opts = opts.merge(atts.pop) 248 end 249 message = validation_error_message(opts[:message]) 250 from_values = opts[:from] == :values 251 where = opts[:where] 252 atts.each do |a| 253 arr = Array(a) 254 next if arr.any?{|x| errors.on(x)} 255 cc = changed_columns 256 next if opts.fetch(:only_if_modified, true) && !new? && !arr.any?{|x| cc.include?(x)} 257 ds = opts[:dataset] || model.dataset 258 ds = if where 259 where.call(ds, self, arr) 260 else 261 vals = arr.map{|x| from_values ? values[x] : get_column_value(x)} 262 next if vals.any?(&:nil?) 263 ds.where(arr.zip(vals)) 264 end 265 ds = yield(ds) if block_given? 266 unless new? 267 h = ds.joined_dataset? ? qualified_pk_hash : pk_hash 268 ds = ds.exclude(h) 269 end 270 errors.add(a, message) unless ds.count == 0 271 end 272 end
Private Instance Methods
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 280 def default_validation_helpers_options(type) 281 DEFAULT_OPTIONS[type] 282 end
Skip validating any attribute that matches one of the allow_* options. 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 288 def validatable_attributes(atts, opts) 289 am, an, ab, m = opts.values_at(:allow_missing, :allow_nil, :allow_blank, :message) 290 from_values = opts[:from] == :values 291 Array(atts).each do |a| 292 next if am && !values.has_key?(a) 293 v = from_values ? values[a] : get_column_value(a) 294 next if an && v.nil? 295 next if ab && model.db.send(:blank_object?, v) 296 if message = yield(a, v, m) 297 errors.add(a, message) 298 end 299 end 300 end
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 304 def validatable_attributes_for_type(type, atts, opts, &block) 305 validatable_attributes(atts, default_validation_helpers_options(type).merge(opts), &block) 306 end
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 311 def validation_error_message(message, *args) 312 message.is_a?(Proc) ? message.call(*args) : message 313 end