class ActiveRecord::Validations::DatabaseConstraintsValidator

Constants

SIZE_VALIDATORS_FOR_TYPE
VALID_CONSTRAINTS

Attributes

constraints[R]

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method
# File lib/active_record/validations/database_constraints.rb, line 16
def initialize(options = {})
  @constraints = Set.new(Array.wrap(options[:in]) + Array.wrap(options[:with]))
  @constraint_validators = {}
  super
end

Public Instance Methods

attribute_validators(klass, attribute) click to toggle source
# File lib/active_record/validations/database_constraints.rb, line 57
def attribute_validators(klass, attribute)
  @constraint_validators[attribute] ||= begin
    column_definition = klass.columns_hash[attribute.to_s]

    unless column_definition
      raise ArgumentError.new("Model #{klass.name} does not have column #{attribute.to_s}!")
    end

    column = ActiveRecord::Validations::TypedColumn.new(column_definition)

    [
      not_null_validator(klass, column),
      size_validator(klass, column),
      range_validator(klass, column),
    ].compact
  end
end
check_validity!() click to toggle source
# File lib/active_record/validations/database_constraints.rb, line 22
def check_validity!
  invalid_constraints = constraints - VALID_CONSTRAINTS

  raise ArgumentError, "You have to specify what constraints to validate for." if constraints.empty?
  raise ArgumentError, "#{invalid_constraints.map(&:inspect).join(',')} is not a valid constraint." unless invalid_constraints.empty?
end
not_null_validator(klass, column) click to toggle source
# File lib/active_record/validations/database_constraints.rb, line 29
def not_null_validator(klass, column)
  return unless constraints.include?(:not_null)
  return if column.null

  ActiveModel::Validations::NotNullValidator.new(attributes: [column.name.to_sym], class: klass)
end
range_validator(klass, column) click to toggle source
# File lib/active_record/validations/database_constraints.rb, line 48
def range_validator(klass, column)
  return unless constraints.include?(:range)
  return unless column.number?

  args = { attributes: [column.name.to_sym], class: klass, allow_nil: true }
  args.merge!(ActiveRecord::DatabaseValidations::MySQL.column_range(column))
  ActiveModel::Validations::NumericalityValidator.new(args)
end
size_validator(klass, column) click to toggle source
# File lib/active_record/validations/database_constraints.rb, line 36
def size_validator(klass, column)
  return unless constraints.include?(:size)
  return unless column.text? || column.binary?

  maximum, type, encoding = ActiveRecord::DatabaseValidations::MySQL.column_size_limit(column)
  validator_class = SIZE_VALIDATORS_FOR_TYPE[type]

  if validator_class && maximum
    validator_class.new(attributes: [column.name.to_sym], class: klass, maximum: maximum, encoding: encoding)
  end
end
validate_each(record, attribute, _value) click to toggle source
# File lib/active_record/validations/database_constraints.rb, line 75
def validate_each(record, attribute, _value)
  attribute_validators(record.class, attribute).each do |validator|
    validator.validate(record)
  end
end