aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/associations')
-rw-r--r--activerecord/lib/active_record/associations/alias_tracker.rb19
-rw-r--r--activerecord/lib/active_record/associations/association_scope.rb15
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb1
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb5
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_association.rb10
5 files changed, 23 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/associations/alias_tracker.rb b/activerecord/lib/active_record/associations/alias_tracker.rb
index 4a5c821607..104de4f69d 100644
--- a/activerecord/lib/active_record/associations/alias_tracker.rb
+++ b/activerecord/lib/active_record/associations/alias_tracker.rb
@@ -4,21 +4,21 @@ module ActiveRecord
module Associations
# Keeps track of table aliases for ActiveRecord::Associations::JoinDependency
class AliasTracker # :nodoc:
- def self.create(connection, initial_table, type_caster)
+ def self.create(connection, initial_table)
aliases = Hash.new(0)
aliases[initial_table] = 1
- new connection, aliases, type_caster
+ new(connection, aliases)
end
- def self.create_with_joins(connection, initial_table, joins, type_caster)
+ def self.create_with_joins(connection, initial_table, joins)
if joins.empty?
- create(connection, initial_table, type_caster)
+ create(connection, initial_table)
else
aliases = Hash.new { |h, k|
h[k] = initial_count_for(connection, k, joins)
}
aliases[initial_table] = 1
- new connection, aliases, type_caster
+ new(connection, aliases)
end
end
@@ -51,17 +51,16 @@ module ActiveRecord
end
# table_joins is an array of arel joins which might conflict with the aliases we assign here
- def initialize(connection, aliases, type_caster)
+ def initialize(connection, aliases)
@aliases = aliases
@connection = connection
- @type_caster = type_caster
end
- def aliased_table_for(table_name, aliased_name)
+ def aliased_table_for(table_name, aliased_name, type_caster)
if aliases[table_name].zero?
# If it's zero, we can have our table_name
aliases[table_name] = 1
- Arel::Table.new(table_name, type_caster: @type_caster)
+ Arel::Table.new(table_name, type_caster: type_caster)
else
# Otherwise, we need to use an alias
aliased_name = @connection.table_alias_for(aliased_name)
@@ -74,7 +73,7 @@ module ActiveRecord
else
aliased_name
end
- Arel::Table.new(table_name, type_caster: @type_caster).alias(table_alias)
+ Arel::Table.new(table_name, type_caster: type_caster).alias(table_alias)
end
end
diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb
index 1593b94f0c..1744dc785f 100644
--- a/activerecord/lib/active_record/associations/association_scope.rb
+++ b/activerecord/lib/active_record/associations/association_scope.rb
@@ -21,7 +21,7 @@ module ActiveRecord
reflection = association.reflection
scope = klass.unscoped
owner = association.owner
- alias_tracker = AliasTracker.create connection, association.klass.table_name, klass.type_caster
+ alias_tracker = AliasTracker.create connection, association.klass.table_name
chain_head, chain_tail = get_chain(reflection, association, alias_tracker)
scope.extending! reflection.extensions
@@ -112,7 +112,11 @@ module ActiveRecord
runtime_reflection = Reflection::RuntimeReflection.new(reflection, association)
previous_reflection = runtime_reflection
reflection.chain.drop(1).each do |refl|
- alias_name = tracker.aliased_table_for(refl.table_name, refl.alias_candidate(name))
+ alias_name = tracker.aliased_table_for(
+ refl.table_name,
+ refl.alias_candidate(name),
+ refl.klass.type_caster
+ )
proxy = ReflectionProxy.new(refl, alias_name)
previous_reflection.next = proxy
previous_reflection = proxy
@@ -138,7 +142,7 @@ module ActiveRecord
# Exclude the scope of the association itself, because that
# was already merged in the #scope method.
reflection.constraints.each do |scope_chain_item|
- item = eval_scope(reflection.klass, table, scope_chain_item, owner)
+ item = eval_scope(reflection, table, scope_chain_item, owner)
if scope_chain_item == refl.scope
scope.merge! item.except(:where, :includes)
@@ -159,9 +163,8 @@ module ActiveRecord
scope
end
- def eval_scope(klass, table, scope, owner)
- predicate_builder = PredicateBuilder.new(TableMetadata.new(klass, table))
- ActiveRecord::Relation.create(klass, table, predicate_builder).instance_exec(owner, &scope)
+ def eval_scope(reflection, table, scope, owner)
+ reflection.build_scope(table).instance_exec(owner, &scope)
end
end
end
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 8cdb508c43..d77fcaf668 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -1114,6 +1114,7 @@ module ActiveRecord
end
def reset_scope # :nodoc:
+ @offsets = {}
@scope = nil
self
end
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index 83e5c23cc4..bc66194aef 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -93,7 +93,7 @@ module ActiveRecord
# joins # => []
#
def initialize(base, associations, joins, eager_loading: true)
- @alias_tracker = AliasTracker.create_with_joins(base.connection, base.table_name, joins, base.type_caster)
+ @alias_tracker = AliasTracker.create_with_joins(base.connection, base.table_name, joins)
@eager_loading = eager_loading
tree = self.class.make_tree associations
@join_root = JoinBase.new base, build(tree, base)
@@ -185,7 +185,8 @@ module ActiveRecord
node.reflection.chain.map { |reflection|
alias_tracker.aliased_table_for(
reflection.table_name,
- table_alias_for(reflection, parent, reflection != node.reflection)
+ table_alias_for(reflection, parent, reflection != node.reflection),
+ reflection.klass.type_caster
)
}
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 97cfec0302..95f16c622e 100644
--- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb
+++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
@@ -40,15 +40,7 @@ module ActiveRecord
constraint = build_constraint(klass, table, key, foreign_table, foreign_key)
- predicate_builder = PredicateBuilder.new(TableMetadata.new(klass, table))
- scope_chain_items = reflection.join_scopes(table, predicate_builder)
- klass_scope = reflection.klass_join_scope(table, predicate_builder)
-
- scope_chain_items.concat [klass_scope].compact
-
- rel = scope_chain_items.inject(scope_chain_items.shift) do |left, right|
- left.merge right
- end
+ rel = reflection.join_scope(table)
if rel && !rel.arel.constraints.empty?
binds += rel.bound_attributes