Module: Jls::Validations::EnforceSchemaRules::ClassMethods

Defined in:
lib/enforce_schema_rules.rb

Instance Method Summary collapse

Instance Method Details

#build_validation_args(options, col_type, validation_option = :invalid) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/enforce_schema_rules.rb', line 68

def build_validation_args(options, col_type, validation_option = :invalid)
  options[validation_option] = I18n.translate('errors.messages')[validation_option]
  options[:message] ||= options[validation_option]
  exclusion_regexp = options[:exclusion_regexp] || /(_at|_on|_id)$|^(id|position|type)$/
  # Determine which columns to validate and symbolize their names
  condition = case col_type
              when :numeric
                lambda { |col| col.name !~ exclusion_regexp && col.number? && col.type != :integer }
              when :not_null
                # I have to exclude boolean types because of a "feature" of the way validates_presence_of
                # handles boolean fields
                # See http://dev.rubyonrails.org/ticket/5090 and http://dev.rubyonrails.org/ticket/3334
                lambda { |col| col.name !~ exclusion_regexp && !col.null && col.type != :boolean }
              else
                lambda { |col| col.name !~ exclusion_regexp && col_type == col.type }
              end
  cols_to_validate = col_type ? columns.find_all { |col| condition[col] } : columns
  # exclude columns
  if except = options[:except]
    except = Array(except).collect { |attr| attr.to_s }
    cols_to_validate = cols_to_validate.reject { |col| except.include?(col.name) }
  end
  attrs = cols_to_validate.collect { |col| col.name.to_sym }
  attrs << options
  attrs
end

#enforce_column_limits(options = {}) ⇒ Object

Enforce string column limits



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/enforce_schema_rules.rb', line 23

def enforce_column_limits(options = {})
  args = build_validation_args(options, :string, :too_long)
  return if args.first.is_a?(Hash)
  options = args.pop
  validates_each(*args) do |record, attr, value|
    limit = record.class.columns_hash[attr.to_s].limit
    if limit
      message = case
      when options[:message].is_a?(String) then options[:message] % {count: limit}
      when limit == 1 then options[:message][:one]
      else options[:message][:other] % {:count => limit} end
      record.errors.add(attr, message) unless value.nil? || value.size <= limit
    end
  end
end

#enforce_integer_columns(options = {}) ⇒ Object

Enforce numericality of integer columns



40
41
42
43
44
45
46
47
48
49
# File 'lib/enforce_schema_rules.rb', line 40

def enforce_integer_columns(options = {})
  # first get the non-integers
  options[:allow_nil] = true
  args = build_validation_args(options, :numeric, :not_a_number)
  validates_numericality_of(*args) unless args.first.is_a? Hash
  # now do the integers
  options[:only_integer] = true
  args = build_validation_args(options, :integer, :not_a_number)
  validates_numericality_of(*args) unless args.first.is_a? Hash
end

#enforce_not_null(options = {}) ⇒ Object

Enfore “not null” columns settings



52
53
54
55
56
# File 'lib/enforce_schema_rules.rb', line 52

def enforce_not_null(options = {})
   args = build_validation_args(options, :not_null, :blank)
   return if args.first.is_a?(Hash)
   validates_presence_of(*args)
end

#enforce_schema_rules(options = {}) ⇒ Object

Call all enforcement methods



13
14
15
16
17
18
19
20
# File 'lib/enforce_schema_rules.rb', line 13

def enforce_schema_rules(options = {})
  return unless connected?
  return unless table_exists?
  enforce_column_limits(options.dup)
  enforce_integer_columns(options.dup)
  enforce_not_null(options.dup)
  enforce_unique_indexes(options.dup)
end

#enforce_unique_indexes(options = {}) ⇒ Object

Enfore unique indexes



59
60
61
62
63
64
65
66
# File 'lib/enforce_schema_rules.rb', line 59

def enforce_unique_indexes(options = {})
  attrs = build_validation_args(options, false, :taken)
  return if attrs.first.is_a?(Hash)
  options = attrs.pop
  connection.indexes(table_name).select { |index| index.unique && index.columns.size == 1 && attrs.include?(index.columns.first.to_sym) }.each do |index|
    validates_uniqueness_of(index.columns.first, options)
  end
end