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
87 def cloneable?(ref)
88   ref[:type] == :many_through_many || ref[:type] == :one_through_many
89 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
93 def default_associated_key_alias
94   self[:uses_left_composite_keys] ? (0...self[:through].first[:left].length).map{|i| :"x_foreign_key_#{i}_x"} : :x_foreign_key_x
95 end
finalize_settings() click to toggle source
    # File lib/sequel/plugins/many_through_many.rb
112 def finalize_settings
113   FINALIZE_SETTINGS
114 end
join_table_alias() click to toggle source

The alias for the first join table.

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

Many through many associations don’t have a reciprocal

    # File lib/sequel/plugins/many_through_many.rb
122 def reciprocal
123   nil
124 end
separate_query_per_table?() click to toggle source

Whether a separate query should be used for each join table.

    # File lib/sequel/plugins/many_through_many.rb
127 def separate_query_per_table?
128   self[:separate_query_per_table]
129 end

Private Instance Methods

_associated_dataset() click to toggle source
    # File lib/sequel/plugins/many_through_many.rb
133 def _associated_dataset
134   ds = associated_class
135   if separate_query_per_table?
136     ds = ds.dataset
137   else
138     (reverse_edges + [final_reverse_edge]).each do |t|
139       h = {:qualify=>:deep}
140       if t[:alias] != t[:table]
141         h[:table_alias] = t[:alias]
142       end
143       ds = ds.join(t[:table], Array(t[:left]).zip(Array(t[:right])), h)
144     end
145   end
146   ds
147 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
188 def calculate_edges
189   es = [{:left_table=>self[:model].table_name, :left_key=>self[:left_primary_key_column]}]
190   self[:through].each do |t|
191     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])
192     es.last[:only_conditions] = t[:only_conditions] if t.include?(:only_conditions)
193     es << {:left_table=>t[:table], :left_key=>t[:right]}
194   end
195   es.last.merge!(:right_key=>right_primary_key, :right_table=>associated_class.table_name)
196   edges = es.map do |e| 
197     h = {:table=>e[:right_table], :left=>e[:left_key], :right=>e[:right_key], :conditions=>e[:conditions], :join_type=>e[:join_type], :block=>e[:block]}
198     h[:only_conditions] = e[:only_conditions] if e.include?(:only_conditions)
199     h
200   end
201   reverse_edges = es.reverse.map{|e| {:table=>e[:left_table], :left=>e[:left_key], :right=>e[:right_key]}}
202   reverse_edges.pop
203   calculate_reverse_edge_aliases(reverse_edges)
204   final_reverse_edge = reverse_edges.pop
205   final_reverse_alias = final_reverse_edge[:alias]
206 
207   h = {:final_edge=>edges.pop,
208        :final_reverse_edge=>final_reverse_edge,
209        :edges=>edges,
210        :reverse_edges=>reverse_edges,
211        :predicate_key=>qualify(final_reverse_alias, edges.first[:right]),
212        :associated_key_table=>final_reverse_edge[:alias],
213   }
214   h.each{|k, v| cached_set(k, v)}
215   h
216 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
171 def calculate_reverse_edge_aliases(reverse_edges)
172   aliases = [associated_class.table_name]
173   reverse_edges.each do |e|
174     table_alias = e[:table]
175     if aliases.include?(table_alias)
176       i = 0
177       table_alias = while true
178         ta = :"#{table_alias}_#{i}"
179         break ta unless aliases.include?(ta)
180         i += 1
181       end
182     end
183     aliases.push(e[:alias] = table_alias)
184   end
185 end
filter_by_associations_limit_key() click to toggle source
    # File lib/sequel/plugins/many_through_many.rb
218 def filter_by_associations_limit_key
219   fe = edges.first
220   Array(qualify(fe[:table], fe[:right])) + Array(qualify(associated_class.table_name, associated_class.primary_key))
221 end
lateral_subquery_filter_limit_strategy_conditions_key() click to toggle source
    # File lib/sequel/plugins/many_through_many.rb
149 def lateral_subquery_filter_limit_strategy_conditions_key
150   qualify(reverse_edges.first[:table], reverse_edges.first[:left])
151 end
lateral_subquery_filter_limit_strategy_filter_dataset(ds, obj) click to toggle source
    # File lib/sequel/plugins/many_through_many.rb
157 def lateral_subquery_filter_limit_strategy_filter_dataset(ds, obj)
158   first_edge, *remaining_edges = edges
159   filter_ds = ds.db.from(first_edge[:table]).
160     select(*qualify(first_edge[:table], first_edge[:right])).
161     where(lateral_subquery_filter_limit_strategy_conditions(obj))
162 
163   remaining_edges.each do |edge|
164     filter_ds = filter_ds.join(edge[:table], Array(edge[:right]).zip(Array(edge[:left])))
165   end
166 
167   ds.where(qualify(self[:model].table_name, self[:left_primary_key]) => filter_ds)
168 end
lateral_subquery_filter_limit_strategy_filter_lateral_dataset(ds) click to toggle source
    # File lib/sequel/plugins/many_through_many.rb
153 def lateral_subquery_filter_limit_strategy_filter_lateral_dataset(ds)
154   ds.where(Array(qualify(edges.first[:table], edges.first[:right])).zip(Array(qualify(self[:model].table_name, edges.first[:left]))))
155 end