Module: Torque::PostgreSQL::Reflection::AbstractReflection

Defined in:
lib/torque/postgresql/reflection/abstract_reflection.rb

Constant Summary collapse

AREL_ATTR =
::Arel::Attributes::Attribute
ARR_NO_CAST =
'bigint'
ARR_CAST =
'bigint[]'

Instance Method Summary collapse

Instance Method Details

#build_id_constraint(klass_attr, source_attr) ⇒ Object

Build the id constraint checking if both types are perfect matching. The klass attribute (left side) will always be a column attribute



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/torque/postgresql/reflection/abstract_reflection.rb', line 45

def build_id_constraint(klass_attr, source_attr)
  return klass_attr.eq(source_attr) unless connected_through_array?

  # Klass and key are associated with the reflection Class
  klass_type = klass.columns_hash[join_keys.key.to_s]

  # Apply an ANY operation which checks if the single value on the left
  # side exists in the array on the right side
  if source_attr.is_a?(AREL_ATTR)
    any_value = [klass_attr, source_attr]
    any_value.reverse! if klass_type.try(:array?)
    return any_value.shift.eq(::Arel::Nodes::NamedFunction.new('ANY', any_value))
  end

  # If the left side is not an array, just use the IN condition
  return klass_attr.in(source_attr) unless klass_type.try(:array)

  # Build the overlap condition (array && array) ensuring that the right
  # side has the same type as the left side
  source_attr = ::Arel::Nodes.build_quoted(Array.wrap(source_attr))
  klass_attr.overlaps(source_attr.cast(klass_type..sql_type))
end

#build_join_constraint(table, foreign_table) ⇒ Object

Manually build the join constraint



35
36
37
38
39
40
41
# File 'lib/torque/postgresql/reflection/abstract_reflection.rb', line 35

def build_join_constraint(table, foreign_table)
  result = build_id_constraint_between(table, foreign_table)
  result = table.create_and([result, klass.send(:type_condition, table)]) \
    if klass.finder_needs_type_condition?

  result
end

#connected_through_array?Boolean

Check if the foreign key actually exists

Returns:

  • (Boolean)


13
14
15
# File 'lib/torque/postgresql/reflection/abstract_reflection.rb', line 13

def connected_through_array?
  false
end

#join_keysObject

TODO: Deprecate this method



69
70
71
# File 'lib/torque/postgresql/reflection/abstract_reflection.rb', line 69

def join_keys
  OpenStruct.new(key: join_primary_key, foreign_key: join_foreign_key)
end

#join_scope(table, foreign_table, foreign_klass) ⇒ Object

Fix where the join_scope method is the one now responsible for building the join condition



19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/torque/postgresql/reflection/abstract_reflection.rb', line 19

def join_scope(table, foreign_table, foreign_klass)
  return super unless connected_through_array?

  predicate_builder = predicate_builder(table)
  scope_chain_items = join_scopes(table, predicate_builder)
  klass_scope       = klass_join_scope(table, predicate_builder)

  klass_scope.where!(build_id_constraint_between(table, foreign_table))
  klass_scope.where!(type => foreign_klass.polymorphic_name) if type
  klass_scope.where!(klass.send(:type_condition, table)) \
    if klass.finder_needs_type_condition?

  scope_chain_items.inject(klass_scope, &:merge!)
end