class Sequel::Plugins::ManyThroughMany::ManyThroughManyAssociationReflection

The AssociationReflection subclass for many_through_many associations.

Constants

FINALIZE_SETTINGS

Public Instance Methods

cloneable?(ref) click to toggle source

many_through_many and one_through_many associations can be clones

# File lib/sequel/plugins/many_through_many.rb, line 87
def cloneable?(ref)
  ref[:type] == :many_through_many || ref[:type] == :one_through_many
end
default_associated_key_alias() click to toggle source

The default associated key alias(es) to use when eager loading associations via eager.

# File lib/sequel/plugins/many_through_many.rb, line 93
def default_associated_key_alias
  self[:uses_left_composite_keys] ? (0...self[:through].first[:left].length).map{|i| :"x_foreign_key_#{i}_x"} : :x_foreign_key_x
end
finalize_settings() click to toggle source
# File lib/sequel/plugins/many_through_many.rb, line 112
def finalize_settings
  FINALIZE_SETTINGS
end
join_table_alias() click to toggle source

The alias for the first join table.

# File lib/sequel/plugins/many_through_many.rb, line 117
def join_table_alias
  final_reverse_edge[:alias]
end
reciprocal() click to toggle source

Many through many associations don't have a reciprocal

# File lib/sequel/plugins/many_through_many.rb, line 122
def reciprocal
  nil
end

Private Instance Methods

_associated_dataset() click to toggle source
# File lib/sequel/plugins/many_through_many.rb, line 128
def _associated_dataset
  ds = associated_class
  (reverse_edges + [final_reverse_edge]).each do |t|
    h = {:qualify=>:deep}
    if t[:alias] != t[:table]
      h[:table_alias] = t[:alias]
    end
    ds = ds.join(t[:table], Array(t[:left]).zip(Array(t[:right])), h)
  end
  ds
end
calculate_edges() click to toggle source

Transform the :through option into a list of edges and reverse edges to use to join tables when loading the association.

# File lib/sequel/plugins/many_through_many.rb, line 158
def calculate_edges
  es = [{:left_table=>self[:model].table_name, :left_key=>self[:left_primary_key_column]}]
  self[:through].each do |t|
    es.last.merge!(:right_key=>t[:left], :right_table=>t[:table], :join_type=>t[:join_type]||self[:graph_join_type], :conditions=>(t[:conditions]||[]).to_a, :block=>t[:block])
    es.last[:only_conditions] = t[:only_conditions] if t.include?(:only_conditions)
    es << {:left_table=>t[:table], :left_key=>t[:right]}
  end
  es.last.merge!(:right_key=>right_primary_key, :right_table=>associated_class.table_name)
  edges = es.map do |e| 
    h = {:table=>e[:right_table], :left=>e[:left_key], :right=>e[:right_key], :conditions=>e[:conditions], :join_type=>e[:join_type], :block=>e[:block]}
    h[:only_conditions] = e[:only_conditions] if e.include?(:only_conditions)
    h
  end
  reverse_edges = es.reverse.map{|e| {:table=>e[:left_table], :left=>e[:left_key], :right=>e[:right_key]}}
  reverse_edges.pop
  calculate_reverse_edge_aliases(reverse_edges)
  final_reverse_edge = reverse_edges.pop
  final_reverse_alias = final_reverse_edge[:alias]

  h = {:final_edge=>edges.pop,
       :final_reverse_edge=>final_reverse_edge,
       :edges=>edges,
       :reverse_edges=>reverse_edges,
       :predicate_key=>qualify(final_reverse_alias, edges.first[:right]),
       :associated_key_table=>final_reverse_edge[:alias],
  }
  h.each{|k, v| cached_set(k, v)}
  h
end
calculate_reverse_edge_aliases(reverse_edges) click to toggle source

Make sure to use unique table aliases when lazy loading or eager loading

# File lib/sequel/plugins/many_through_many.rb, line 141
def calculate_reverse_edge_aliases(reverse_edges)
  aliases = [associated_class.table_name]
  reverse_edges.each do |e|
    table_alias = e[:table]
    if aliases.include?(table_alias)
      i = 0
      table_alias = loop do
        ta = :"#{table_alias}_#{i}"
        break ta unless aliases.include?(ta)
        i += 1
      end
    end
    aliases.push(e[:alias] = table_alias)
  end
end
filter_by_associations_limit_key() click to toggle source
# File lib/sequel/plugins/many_through_many.rb, line 188
def filter_by_associations_limit_key
  fe = edges.first
  Array(qualify(fe[:table], fe[:right])) + Array(qualify(associated_class.table_name, associated_class.primary_key))
end