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.
Public Instance Methods
Freeze constraint validations data when freezing model class.
# File lib/sequel/plugins/constraint_validations.rb 94 def freeze 95 @constraint_validations.freeze.each(&:freeze) 96 @constraint_validation_reflections.freeze.each_value do |v| 97 v.freeze 98 v.each(&:freeze) 99 end 100 @constraint_validation_options.freeze.each_value(&:freeze) 101 102 super 103 end
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 135 def constraint_validation_array(r, reflections) 136 opts = {} 137 opts[:message] = r[:message] if r[:message] 138 opts[:allow_nil] = true if db.typecast_value(:boolean, r[:allow_nil]) 139 type = r[:validation_type].to_sym 140 arg = r[:argument] 141 column = r[:column] 142 143 case type 144 when :like, :ilike 145 arg = constraint_validation_like_to_regexp(arg, type == :ilike) 146 type = :format 147 when :exact_length, :min_length, :max_length 148 arg = arg.to_i 149 when :length_range 150 arg = constraint_validation_int_range(arg) 151 when :format 152 arg = Regexp.new(arg) 153 when :iformat 154 arg = Regexp.new(arg, Regexp::IGNORECASE) 155 type = :format 156 when :includes_str_array 157 arg = arg.split(',') 158 type = :includes 159 when :includes_int_array 160 arg = arg.split(',').map(&:to_i) 161 type = :includes 162 when :includes_int_range 163 arg = constraint_validation_int_range(arg) 164 type = :includes 165 when *OPERATOR_MAP.keys 166 arg = arg.to_i if type.to_s =~ /\Aint_/ 167 operator = OPERATOR_MAP[type] 168 type = :operator 169 end 170 171 column = if type == :unique 172 column.split(',').map(&:to_sym) 173 else 174 column.to_sym 175 end 176 177 if type_opts = @constraint_validation_options[type] 178 opts.merge!(type_opts) 179 end 180 181 reflection_opts = opts.dup 182 a = [:"validates_#{type}"] 183 184 if operator 185 a << operator 186 reflection_opts[:operator] = operator 187 end 188 189 if arg 190 a << arg 191 reflection_opts[:argument] = arg 192 end 193 194 a << column 195 unless opts.empty? 196 a << opts 197 end 198 199 if column.is_a?(Array) && column.length == 1 200 column = column.first 201 end 202 (reflections[column] ||= []) << [type, reflection_opts] 203 204 a 205 end
Return a range of integers assuming the argument is in 1..2 or 1…2 format.
# File lib/sequel/plugins/constraint_validations.rb 209 def constraint_validation_int_range(arg) 210 arg =~ /(\d+)\.\.(\.)?(\d+)/ 211 Range.new($1.to_i, $3.to_i, $2 == '.') 212 end
Transform the LIKE pattern string argument into a Regexp argument suitable for use with validates_format.
# File lib/sequel/plugins/constraint_validations.rb 216 def constraint_validation_like_to_regexp(arg, case_insensitive) 217 arg = Regexp.escape(arg).gsub(/%%|%|_/) do |s| 218 case s 219 when '%%' 220 '%' 221 when '%' 222 '.*' 223 when '_' 224 '.' 225 end 226 end 227 arg = "\\A#{arg}\\z" 228 229 if case_insensitive 230 Regexp.new(arg, Regexp::IGNORECASE) 231 else 232 Regexp.new(arg) 233 end 234 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 113 def parse_constraint_validations 114 db.extension(:_model_constraint_validations) 115 116 unless hash = Sequel.synchronize{db.constraint_validations} 117 hash = {} 118 db.from(constraint_validations_table).each do |r| 119 (hash[r[:table]] ||= []) << r 120 end 121 Sequel.synchronize{db.constraint_validations = hash} 122 end 123 124 if @dataset 125 ds = @dataset.with_quote_identifiers(false) 126 table_name = ds.literal(ds.first_source_table) 127 reflections = {} 128 @constraint_validations = (Sequel.synchronize{hash[table_name]} || []).map{|r| constraint_validation_array(r, reflections)} 129 @constraint_validation_reflections = reflections 130 end 131 end