Module: WhereAny

Defined in:
lib/where_any.rb,
lib/where_any/version.rb

Constant Summary collapse

VERSION =
'0.1.2'

Instance Method Summary collapse

Instance Method Details

#array_type_for_attribute(name) ⇒ ActiveRecord::Type::Value

Parameters:

  • name (String)

Returns:

  • (ActiveRecord::Type::Value)


8
9
10
11
12
13
14
15
16
17
# File 'lib/where_any.rb', line 8

def array_type_for_attribute(name)
  element_type = type_for_attribute(name)

  if (type = element_type.type)
    ActiveRecord::Type.lookup(type, array: true)
  else
    # For unknown types (e.g. from projected columns), use a generic array type.
    ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.new(element_type)
  end
end

#bind_array(name, value) ⇒ Arel::Nodes::Node

Parameters:

  • name (String)
  • value (Object)

Returns:

  • (Arel::Nodes::Node)


32
33
34
35
36
37
# File 'lib/where_any.rb', line 32

def bind_array(name, value)
  attribute_type  = array_type_for_attribute(name)
  query_attribute = ActiveRecord::Relation::QueryAttribute.new(name.to_s, value, attribute_type)

  Arel::Nodes::BindParam.new(query_attribute)
end

#bind_param(name, value) ⇒ Arel::Nodes::Node

Parameters:

  • name (String)
  • value (Object)

Returns:

  • (Arel::Nodes::Node)


22
23
24
25
26
27
# File 'lib/where_any.rb', line 22

def bind_param(name, value)
  attribute_type  = type_for_attribute(name)
  query_attribute = ActiveRecord::Relation::QueryAttribute.new(name.to_s, value, attribute_type)

  Arel::Nodes::BindParam.new(query_attribute)
end

#where_any(column, values) ⇒ ActiveRecord::Relation

Parameters:

  • column (String, Symbol)
  • values (Array<Object>)

Returns:

  • (ActiveRecord::Relation)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/where_any.rb', line 42

def where_any(column, values)
  return none if values.blank?

  if (includes_null = values.include?(nil))
    values = values.compact
    return where(column => nil) if values.empty?
  end

  arel_column   = arel_table[column]
  any_of_values = Arel::Nodes::NamedFunction.new('ANY', [bind_array(column, values)])

  scope = where(arel_column.eq(any_of_values))
  scope = scope.or(where(column => nil)) if includes_null

  scope
end

#where_none(column, values) ⇒ ActiveRecord::Relation

Parameters:

  • column (String, Symbol)
  • values (Array<Object>)

Returns:

  • (ActiveRecord::Relation)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/where_any.rb', line 62

def where_none(column, values)
  return all if values.blank?

  if (includes_null = values.include?(nil))
    values = values.compact
    return where.not(column => nil) if values.empty?
  end

  arel_column   = arel_table[column]
  all_of_values = Arel::Nodes::NamedFunction.new('ALL', [bind_array(column, values)])

  scope = where(arel_column.not_eq(all_of_values))
  scope = scope.where.not(column => nil) if includes_null

  scope
end