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 167 def calculate_edges 168 es = [{:left_table=>self[:model].table_name, :left_key=>self[:left_primary_key_column]}] 169 self[:through].each do |t| 170 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]) 171 es.last[:only_conditions] = t[:only_conditions] if t.include?(:only_conditions) 172 es << {:left_table=>t[:table], :left_key=>t[:right]} 173 end 174 es.last.merge!(:right_key=>right_primary_key, :right_table=>associated_class.table_name) 175 edges = es.map do |e| 176 h = {:table=>e[:right_table], :left=>e[:left_key], :right=>e[:right_key], :conditions=>e[:conditions], :join_type=>e[:join_type], :block=>e[:block]} 177 h[:only_conditions] = e[:only_conditions] if e.include?(:only_conditions) 178 h 179 end 180 reverse_edges = es.reverse.map{|e| {:table=>e[:left_table], :left=>e[:left_key], :right=>e[:right_key]}} 181 reverse_edges.pop 182 calculate_reverse_edge_aliases(reverse_edges) 183 final_reverse_edge = reverse_edges.pop 184 final_reverse_alias = final_reverse_edge[:alias] 185 186 h = {:final_edge=>edges.pop, 187 :final_reverse_edge=>final_reverse_edge, 188 :edges=>edges, 189 :reverse_edges=>reverse_edges, 190 :predicate_key=>qualify(final_reverse_alias, edges.first[:right]), 191 :associated_key_table=>final_reverse_edge[:alias], 192 } 193 h.each{|k, v| cached_set(k, v)} 194 h 195 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 150 def calculate_reverse_edge_aliases(reverse_edges) 151 aliases = [associated_class.table_name] 152 reverse_edges.each do |e| 153 table_alias = e[:table] 154 if aliases.include?(table_alias) 155 i = 0 156 table_alias = while true 157 ta = :"#{table_alias}_#{i}" 158 break ta unless aliases.include?(ta) 159 i += 1 160 end 161 end 162 aliases.push(e[:alias] = table_alias) 163 end 164 end
filter_by_associations_limit_key()
click to toggle source
# File lib/sequel/plugins/many_through_many.rb 197 def filter_by_associations_limit_key 198 fe = edges.first 199 Array(qualify(fe[:table], fe[:right])) + Array(qualify(associated_class.table_name, associated_class.primary_key)) 200 end