module Sequel::Plugins::ConstraintValidations::ClassMethods
Attributes
A hash of reflections of constraint validations. Keys are type name symbols. Each value is an array of pairs, with the first element being the validation type symbol (e.g. :presence) and the second element being options for the validation. If the validation takes an argument, it appears as the :argument entry in the validation option hash.
An array of validation method call arrays. Each array is an array that is splatted to send to perform a validation via validation_helpers.
The name of the table containing the constraint validations metadata.
Private Instance Methods
Given a specific database constraint validation metadata row hash, transform it in an validation method call array suitable for splatting to send.
# File lib/sequel/plugins/constraint_validations.rb, line 125 def constraint_validation_array(r, reflections) opts = {} opts[:message] = r[:message] if r[:message] opts[:allow_nil] = true if db.typecast_value(:boolean, r[:allow_nil]) type = r[:validation_type].to_sym arg = r[:argument] column = r[:column] case type when :like, :ilike arg = constraint_validation_like_to_regexp(arg, type == :ilike) type = :format when :exact_length, :min_length, :max_length arg = arg.to_i when :length_range arg = constraint_validation_int_range(arg) when :format arg = Regexp.new(arg) when :iformat arg = Regexp.new(arg, Regexp::IGNORECASE) type = :format when :includes_str_array arg = arg.split(',') type = :includes when :includes_int_array arg = arg.split(',').map{|x| x.to_i} type = :includes when :includes_int_range arg = constraint_validation_int_range(arg) type = :includes end column = if type == :unique column.split(',').map{|c| c.to_sym} else column.to_sym end if type_opts = @constraint_validation_options[type] opts = opts.merge(type_opts) end reflection_opts = opts a = [:"validates_#{type}"] if arg a << arg reflection_opts = reflection_opts.merge(:argument=>arg) end a << column unless opts.empty? a << opts end if column.is_a?(Array) && column.length == 1 column = column.first end (reflections[column] ||= []) << [type, reflection_opts] a end
Return a range of integers assuming the argument is in 1..2 or 1…2 format.
# File lib/sequel/plugins/constraint_validations.rb, line 189 def constraint_validation_int_range(arg) arg =~ /(\d+)\.\.(\.)?(\d+)/ Range.new($1.to_i, $3.to_i, $2 == '.') end
Transform the LIKE pattern string argument into a Regexp argument suitable for use with validates_format.
# File lib/sequel/plugins/constraint_validations.rb, line 196 def constraint_validation_like_to_regexp(arg, case_insensitive) arg = Regexp.escape(arg).gsub(/%%|%|_/) do |s| case s when '%%' '%' when '%' '.*' when '_' '.' end end arg = "\\A#{arg}\\z" if case_insensitive Regexp.new(arg, Regexp::IGNORECASE) else Regexp.new(arg) end end
If the database has not already parsed constraint validation metadata, then run a query to get the metadata data and transform it into arrays of validation method calls.
If this model has associated dataset, use the model's table name to get the validations for just this model.
# File lib/sequel/plugins/constraint_validations.rb, line 102 def parse_constraint_validations db.extend(DatabaseMethods) unless hash = Sequel.synchronize{db.constraint_validations} hash = {} db.from(constraint_validations_table).each do |r| (hash[r[:table]] ||= []) << r end Sequel.synchronize{db.constraint_validations = hash} end if @dataset ds = @dataset.clone ds.quote_identifiers = false table_name = ds.literal(ds.first_source_table) reflections = {} @constraint_validations = (Sequel.synchronize{hash[table_name]} || []).map{|r| constraint_validation_array(r, reflections)} @constraint_validation_reflections = reflections end end