diff options
Diffstat (limited to 'activerecord/lib/active_record')
3 files changed, 26 insertions, 13 deletions
diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb index ab102b2b8f..94847bc2ae 100644 --- a/activerecord/lib/active_record/associations/association_scope.rb +++ b/activerecord/lib/active_record/associations/association_scope.rb @@ -75,10 +75,16 @@ module ActiveRecord foreign_key = reflection.active_record_primary_key end + conditions = self.conditions[i] + if reflection == chain.last scope = scope.where(table[key].eq(owner[foreign_key])) - conditions[i].each do |condition| + 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 @@ -87,12 +93,16 @@ module ActiveRecord end else constraint = table[key].eq(foreign_table[foreign_key]) - join = join(foreign_table, constraint) - scope = scope.joins(join) + 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[i].empty? - scope = scope.where(sanitize(conditions[i], table)) + unless conditions.empty? + scope = scope.where(sanitize(conditions, table)) end end end diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb index c32753782f..03963ab060 100644 --- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb @@ -62,6 +62,7 @@ module ActiveRecord def join_to(relation) tables = @tables.dup foreign_table = parent_table + foreign_klass = parent.active_record # The chain starts with the target table, but we want to end with it here (makes # more sense in this context), so we reverse @@ -91,14 +92,17 @@ module ActiveRecord constraint = build_constraint(reflection, table, key, foreign_table, foreign_key) - unless conditions[i].empty? - constraint = constraint.and(sanitize(conditions[i], table)) + conditions = self.conditions[i].dup + conditions << { reflection.type => foreign_klass.base_class.name } if reflection.type + + unless conditions.empty? + constraint = constraint.and(sanitize(conditions, table)) end relation.from(join(table, constraint)) # The current table in this iteration becomes the foreign table in the next - foreign_table = table + foreign_table, foreign_klass = table, reflection.klass end relation diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index bcba85d7a4..b1bb1b0f7f 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -212,7 +212,7 @@ module ActiveRecord end def type - @type ||= "#{options[:as]}_type" + @type ||= options[:as] && "#{options[:as]}_type" end def primary_key_column @@ -280,9 +280,7 @@ module ActiveRecord # in the #chain. The inside arrays are simply conditions (and each condition may itself be # a hash, array, arel predicate, etc...) def conditions - conditions = [options[:conditions]].compact - conditions << { type => active_record.base_class.name } if options[:as] - [conditions] + [[options[:conditions]].compact] end alias :source_macro :macro @@ -378,7 +376,8 @@ module ActiveRecord # Holds all the meta-data about a :through association as it was specified # in the Active Record class. class ThroughReflection < AssociationReflection #:nodoc: - delegate :foreign_key, :foreign_type, :association_foreign_key, :active_record_primary_key, :to => :source_reflection + delegate :foreign_key, :foreign_type, :association_foreign_key, + :active_record_primary_key, :type, :to => :source_reflection # Gets the source of the through reflection. It checks both a singularized # and pluralized form for <tt>:belongs_to</tt> or <tt>:has_many</tt>. |