Class: ROM::SQL::Association::ManyToMany

Inherits:
ROM::SQL::Association show all
Defined in:
lib/rom/sql/association/many_to_many.rb

Direct Known Subclasses

OneToOneThrough

Instance Attribute Summary collapse

Attributes inherited from ROM::SQL::Association

#as, #relation, #result, #source, #target

Instance Method Summary collapse

Methods inherited from ROM::SQL::Association

#qualify

Constructor Details

#initializeManyToMany

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of ManyToMany.



12
13
14
15
16
17
# File 'lib/rom/sql/association/many_to_many.rb', line 12

def initialize(*)
  super
  @through = Relation::Name[
    options[:through] || options[:through_relation], options[:through]
  ]
end

Instance Attribute Details

#throughObject (readonly)



5
6
7
# File 'lib/rom/sql/association/many_to_many.rb', line 5

def through
  @through
end

Instance Method Details

#associate(relations, children, parent) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



53
54
55
56
57
58
59
# File 'lib/rom/sql/association/many_to_many.rb', line 53

def associate(relations, children, parent)
  ((spk, sfk), (tfk, tpk)) = join_key_map(relations)

  children.map { |tuple|
    { sfk => tuple.fetch(spk), tfk => parent.fetch(tpk) }
  }
end

#call(relations) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rom/sql/association/many_to_many.rb', line 20

def call(relations)
  join_rel = join_relation(relations)
  assocs = join_rel.associations

  left = assocs[target].call(relations)
  right = relations[target.relation]

  left_fk = join_rel.foreign_key(source.relation)

  columns = right.header.exclude(left_fk).qualified.to_a
  columns << left_fk unless right.header.names.include?(left_fk)

  relation = left
    .inner_join(source, join_keys(relations))
    .select(*columns)
    .order(*right.header.project(*right.primary_key).qualified)

  relation.with(attributes: relation.header.names)
end

#combine_keys(relations) ⇒ Object



48
49
50
# File 'lib/rom/sql/association/many_to_many.rb', line 48

def combine_keys(relations)
  Hash[*with_keys(relations)]
end

#join_keys(relations) ⇒ Object



41
42
43
44
45
# File 'lib/rom/sql/association/many_to_many.rb', line 41

def join_keys(relations)
  with_keys(relations) { |source_key, target_key|
    { qualify(source, source_key) => qualify(through, target_key) }
  }
end

#join_relation(relations) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



62
63
64
# File 'lib/rom/sql/association/many_to_many.rb', line 62

def join_relation(relations)
  relations[through.relation]
end