module Sequel::Plugins::ManyThroughMany::DatasetMethods

Private Instance Methods

many_through_many_association_filter_expression(op, ref, obj) click to toggle source

Use a subquery to filter rows to those related to the given associated object

    # File lib/sequel/plugins/many_through_many.rb
304 def many_through_many_association_filter_expression(op, ref, obj)
305   lpks = ref[:left_primary_key_columns]
306   lpks = lpks.first if lpks.length == 1
307   lpks = ref.qualify(model.table_name, lpks)
308   edges = ref.edges
309   first, rest = edges.first, edges[1..-1]
310   ds = model.db[first[:table]].select(*Array(ref.qualify(first[:table], first[:right])))
311   rest.each{|e| ds = ds.join(e[:table], e.fetch(:only_conditions, (Array(e[:right]).zip(Array(e[:left])) + e[:conditions])), :table_alias=>ds.unused_table_alias(e[:table]), :qualify=>:deep, &e[:block])}
312   last_alias = if rest.empty?
313     first[:table]
314   else
315     last_join = ds.opts[:join].last
316     last_join.table_alias || last_join.table
317   end
318 
319   meths = if obj.is_a?(Sequel::Dataset)
320     ref.qualify(obj.model.table_name, ref.right_primary_keys)
321   else
322     ref.right_primary_key_methods
323   end
324 
325   expr = association_filter_key_expression(ref.qualify(last_alias, Array(ref.final_edge[:left])), meths, obj)
326   unless expr == SQL::Constants::FALSE
327     ds = ds.where(expr).exclude(SQL::BooleanExpression.from_value_pairs(ds.opts[:select].zip([]), :OR))
328     expr = SQL::BooleanExpression.from_value_pairs(lpks=>ds)
329     expr = add_association_filter_conditions(ref, obj, expr)
330   end
331 
332   association_filter_handle_inversion(op, expr, Array(lpks))
333 end
one_through_many_association_filter_expression(op, ref, obj)