Class: OverlapValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/validates_overlap/overlap_validator.rb

Defined Under Namespace

Classes: UnsupportedColumnType

Constant Summary collapse

RANGE_COLUMN_TYPES =

PostgreSQL range column types usable with the single-attribute form

%i[tsrange tstzrange daterange int4range int8range numrange].freeze

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ OverlapValidator

Returns a new instance of OverlapValidator.



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/validates_overlap/overlap_validator.rb', line 13

def initialize(args)
  attributes_are_range(args[:attributes])
  reject_range_column_options(args)
  model_class = args[:class]

  super

  # defines record.overlapping_records on the validated model
  model_class.include(ValidatesOverlap::OverlappingRecords) if model_class
  if options[:load_overlapped]
    ValidatesOverlap.deprecator.warn('load_overlapped is deprecated and will be removed in validates_overlap 2.0 — use record.overlapping_records instead')
  end
end

Instance Method Details

#add_overlap_error(record) ⇒ Object

Add this validation's configured error to the record. Also used by ValidatesOverlap::RescueExclusionViolation so a constraint violation caught in the race window lands on exactly the same keys as a validator-caught one



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/validates_overlap/overlap_validator.rb', line 53

def add_overlap_error(record)
  if record.respond_to? attributes.first
    if options[:message_title].is_a?(Array)
      options[:message_title].each do |key|
        record.errors.add(key, options[:message_content] || :overlap)
      end
    else
      record.errors.add(options[:message_title] || attributes.first, options[:message_content] || :overlap)
    end
  else
    record.errors.add(options[:message_title] || :base, options[:message_content] || :overlap)
  end
end

#overlapping_records_for(record) ⇒ Object

Build and return the overlap query for the given record — used by ValidatesOverlap::OverlappingRecords#overlapping_records



29
30
31
32
33
# File 'lib/validates_overlap/overlap_validator.rb', line 29

def overlapping_records_for(record)
  reject_unsupported_column_types(record)
  relation, sql_conditions, sql_values = initialize_query(record, options)
  get_overlapped(relation, sql_conditions, sql_values)
end

#validate(record) ⇒ Object

NOTE: Rails registers ONE validator instance per model class, shared by every validation of that class (including concurrent ones) — so the query being built must never be stored on the validator itself (issue #50)



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/validates_overlap/overlap_validator.rb', line 38

def validate(record)
  reject_unsupported_column_types(record)
  relation, sql_conditions, sql_values = initialize_query(record, options)
  if overlapped_exists?(relation, sql_conditions, sql_values)
    if options[:load_overlapped]
      record.instance_variable_set(:@overlapped_records, get_overlapped(relation, sql_conditions, sql_values))
    end

    add_overlap_error(record)
  end
end