module Sequel::Plugins::ConstraintValidations::ClassMethods

Attributes

constraint_validation_reflections[R]

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.

constraint_validations[R]

An array of validation method call arrays. Each array is an array that is splatted to send to perform a validation via validation_helpers.

constraint_validations_table[R]

The name of the table containing the constraint validations metadata.

Public Instance Methods

freeze() click to toggle source

Freeze constraint validations data when freezing model class.

Calls superclass method
    # 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

constraint_validation_array(r, reflections) click to toggle source

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
constraint_validation_int_range(arg) click to toggle source

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
constraint_validation_like_to_regexp(arg, case_insensitive) click to toggle source

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
parse_constraint_validations() click to toggle source

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