Module: ActiveRecord::HashOptions

Defined in:
lib/active_record/hash_options.rb,
lib/active_record/hash_options/helpers.rb,
lib/active_record/hash_options/version.rb,
lib/active_record/hash_options/operators.rb,
lib/active_record/hash_options/enumerable.rb

Defined Under Namespace

Modules: Enumerable, Helpers Classes: GT, GTE, GenericOp, ILIKE, INSENSITIVE, LIKE, LT, LTE, NOT_LIKE, REGEXP

Constant Summary collapse

VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.compare_array_column(actual_val, value) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/active_record/hash_options.rb', line 66

def self.compare_array_column(actual_val, value)
  case value
  when Regexp
    actual_val =~ value
  when Array
    value.include?(actual_val)
  when Range
    value.cover?(actual_val)
  when ActiveRecord::HashOptions::GenericOp
    # NOTE: The `nil?` check in `filter_array` may skip this comparison and short circuit to a false
    value.call(actual_val)
  else # NilClass, String, Integer
    # NOTE: this treats `x == nil` the same as `x IS NULL`
    actual_val == value
  end
end

.extended(mod) ⇒ Object



9
10
11
# File 'lib/active_record/hash_options.rb', line 9

def self.extended(mod)
  ActiveRecord::HashOptions.register_my_handler(mod)
end

.filter(scope_or_array, conditions, negate = false) ⇒ Object



35
36
37
38
39
40
41
# File 'lib/active_record/hash_options.rb', line 35

def self.filter(scope_or_array, conditions, negate = false)
  if scope_or_array.kind_of?(Array)
    filter_array(scope_or_array, conditions, negate)
  else
    filter_scope(scope_or_array, conditions, negate)
  end
end

.filter_array(array, conditions, negate) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/active_record/hash_options.rb', line 51

def self.filter_array(array, conditions, negate)
  array.select do |rec|
    conditions.all? do |name, value|
      actual_val = rec.send(name)
      # not thrilled about special cases, but `x in [..., nil]` and `x == nil` are the only cases
      # that handle negation for a `nil` / `null` value correctly
      if actual_val.nil? && (value != nil || value.kind_of?(Array) && !value.include?(nil))
        false
      else
        compare_array_column(actual_val, value) ? !negate : negate
      end
    end
  end
end

.filter_scope(scope, conditions, negate) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/active_record/hash_options.rb', line 43

def self.filter_scope(scope, conditions, negate)
  if negate
    scope.where.not(conditions)
  else
    scope.where(conditions)
  end
end

.inherited(mod) ⇒ Object



13
14
15
# File 'lib/active_record/hash_options.rb', line 13

def self.inherited(mod)
  ActiveRecord::HashOptions.register_my_handler(mod)
end

.register_my_handler(mod) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/active_record/hash_options.rb', line 17

def self.register_my_handler(mod)
  if mod < ActiveRecord::Base && mod.kind_of?(Class)
    mod.predicate_builder.register_handler(GT, GT.arel_proc)
    mod.predicate_builder.register_handler(LT, LT.arel_proc)
    mod.predicate_builder.register_handler(GTE, GTE.arel_proc)
    mod.predicate_builder.register_handler(LTE, LTE.arel_proc)
    mod.predicate_builder.register_handler(INSENSITIVE, INSENSITIVE.arel_proc)
    mod.predicate_builder.register_handler(LIKE, LIKE.arel_proc)
    mod.predicate_builder.register_handler(NOT_LIKE, NOT_LIKE.arel_proc)
    # for postgres:
    mod.predicate_builder.register_handler(ILIKE, ILIKE.arel_proc)

    # NOTE: Probably want Regexp over REGEXP (e.g.: where(:name => /value/i))
    mod.predicate_builder.register_handler(Regexp, REGEXP.arel_proc)
    mod.predicate_builder.register_handler(REGEXP, REGEXP.arel_proc)
  end
end