From 093c92ea308a050a5e66c09d650b378e4ddd3515 Mon Sep 17 00:00:00 2001 From: Tim Chambers Date: Thu, 8 Nov 2018 15:43:50 -0800 Subject: [PATCH] Rewrite add constraints to support Rails 4 using bind values except where sub-select on group values --- .../arish/associations/association_scope.rb | 80 +++++++++++-------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/lib/grouped_scope/arish/associations/association_scope.rb b/lib/grouped_scope/arish/associations/association_scope.rb index 29254ec..c13501a 100644 --- a/lib/grouped_scope/arish/associations/association_scope.rb +++ b/lib/grouped_scope/arish/associations/association_scope.rb @@ -11,76 +11,88 @@ class AssociationScope < ActiveRecord::Associations::AssociationScope # up will only work for the has_many. https://gist.github.com/1434980 # # We will just have to monitor rails every now and then and update this. Thankfully this - # copy is only used in a group scope. FYI, our one line change is commented below. + # copy is only used in a group scope. + def add_constraints(scope) tables = construct_tables - + chain.each_with_index do |reflection, i| table, foreign_table = tables.shift, tables.first - + if reflection.source_macro == :has_and_belongs_to_many join_table = tables.shift - + scope = scope.joins(join( - join_table, - table[reflection.association_primary_key]. - in(join_table[reflection.association_foreign_key]) - )) - + join_table, + table[reflection.association_primary_key]. + eq(join_table[reflection.association_foreign_key]) + )) + table, foreign_table = join_table, tables.first end - + if reflection.source_macro == :belongs_to if reflection.options[:polymorphic] - key = reflection.association_primary_key(klass) + key = reflection.association_primary_key(self.klass) else key = reflection.association_primary_key end - + foreign_key = reflection.foreign_key else key = reflection.foreign_key foreign_key = reflection.active_record_primary_key end - - conditions = self.conditions[i] - + if reflection == chain.last - # GroupedScope changed this line. - # scope = scope.where(table[key].eq(owner[foreign_key])) + # GroupedScope changed this area. + scope = if owner.group.present? + # binding.pry + #bind_val = bind scope, table.table_name, key.to_s, owner.group.ids_sql scope.where(table[key].in(owner.group.ids_sql)) else - scope.where(table[key].eq(owner[foreign_key])) + bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key] + scope.where(table[key].eq(bind_val)) end - + if reflection.type - scope = scope.where(table[reflection.type].eq(owner.class.base_class.name)) - end - - conditions.each do |condition| - if options[:through] && condition.is_a?(Hash) - condition = { table.name => condition } - end - - scope = scope.where(interpolate(condition)) + value = owner.class.base_class.name + bind_val = bind scope, table.table_name, reflection.type.to_s, value + scope = scope.where(table[reflection.type].eq(bind_val)) end else constraint = table[key].eq(foreign_table[foreign_key]) - + if reflection.type type = chain[i + 1].klass.base_class.name constraint = constraint.and(table[reflection.type].eq(type)) end - + scope = scope.joins(join(foreign_table, constraint)) - - unless conditions.empty? - scope = scope.where(sanitize(conditions, table)) + end + + is_first_chain = i == 0 + klass = is_first_chain ? self.klass : reflection.klass + + # Exclude the scope of the association itself, because that + # was already merged in the #scope method. + scope_chain[i].each do |scope_chain_item| + item = eval_scope(klass, scope_chain_item) + + if scope_chain_item == self.reflection.scope + scope.merge! item.except(:where, :includes) end + + if is_first_chain + scope.includes! item.includes_values + end + + scope.where_values += item.where_values + scope.order_values |= item.order_values end end - + scope end