Class: ActsAsSpan::NoOverlapValidator

Inherits:
ActiveModel::Validator
  • Object
show all
Defined in:
lib/acts_as_span/no_overlap_validator.rb

Instance Method Summary collapse

Instance Method Details

#temporally_overlapping_for(record) ⇒ Object

TODO add back condition for start_date nil TODO add configuration for span configuration



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/acts_as_span/no_overlap_validator.rb', line 28

def temporally_overlapping_for(record)
  scope = record.instance_eval(&options[:scope])

  start_date = record.start_date || Date.current
  end_date = record.end_date
  arel_table = record.class.arel_table

  if end_date
    scope.where(
      arel_table[:start_date].lteq(end_date).
      and(
        arel_table[:end_date].gteq(start_date).
        or(arel_table[:end_date].eq(nil))
      )
    )
  else
    scope.where(
      arel_table[:end_date].gteq(start_date).
      or(arel_table[:end_date].eq(nil))
    )
  end
end

#validate(record) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/acts_as_span/no_overlap_validator.rb', line 5

def validate(record)
  overlapping_records = temporally_overlapping_for(record)
  instance_scope = options[:instance_scope].is_a?(Proc) ? record.instance_eval(&options[:instance_scope]) : true

  if overlapping_records.any? && instance_scope

    error_type = overlapping_records.size == 1 ? "no_overlap.one" : "no_overlap.other"

    record.errors.add(
      :base,
      error_type.to_sym,
      model_name: record.class.model_name.human,
      model_name_plural: record.class.model_name.plural.humanize,
      start_date: record.start_date,
      end_date: record.end_date,
      count: overlapping_records.size,
      overlapping_records_s: overlapping_records.join(",")
    )
  end
end