aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2017-05-30 18:08:22 +0930
committerMatthew Draper <matthew@trebex.net>2017-05-30 18:20:58 +0930
commit75226cc7d8224762932d4f5593ea366f25cbf61e (patch)
tree97ad5d4e90083b612037de88d362679f38ebad64 /activerecord/lib
parent6847877a30fd8d578f72db0cf40674f71a9b6286 (diff)
parent5632f73042bc543d59e6f3e913e0d2cd44b54a65 (diff)
downloadrails-75226cc7d8224762932d4f5593ea366f25cbf61e.tar.gz
rails-75226cc7d8224762932d4f5593ea366f25cbf61e.tar.bz2
rails-75226cc7d8224762932d4f5593ea366f25cbf61e.zip
Merge pull request #29098 from kamipo/fix_association_with_extension_issues
Fix association with extension issues
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/associations/association.rb10
-rw-r--r--activerecord/lib/active_record/associations/association_scope.rb2
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb3
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb33
-rw-r--r--activerecord/lib/active_record/reflection.rb4
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb2
-rw-r--r--activerecord/lib/active_record/scoping/named.rb11
7 files changed, 33 insertions, 32 deletions
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index 6b13e6936f..ee2e79889f 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -133,6 +133,16 @@ module ActiveRecord
AssociationRelation.create(klass, klass.arel_table, klass.predicate_builder, self).merge!(klass.all)
end
+ def extensions
+ extensions = klass.default_extensions | reflection.extensions
+
+ if scope = reflection.scope
+ extensions |= klass.unscoped.instance_exec(owner, &scope).extensions
+ end
+
+ extensions
+ end
+
# Loads the \target if needed and returns it.
#
# This method is abstract in the sense that it relies on +find_target+,
diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb
index 120d75416c..1593b94f0c 100644
--- a/activerecord/lib/active_record/associations/association_scope.rb
+++ b/activerecord/lib/active_record/associations/association_scope.rb
@@ -24,7 +24,7 @@ module ActiveRecord
alias_tracker = AliasTracker.create connection, association.klass.table_name, klass.type_caster
chain_head, chain_tail = get_chain(reflection, association, alias_tracker)
- scope.extending! Array(reflection.options[:extend])
+ scope.extending! reflection.extensions
add_constraints(scope, owner, reflection, chain_head, chain_tail)
end
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 62c944fce3..edc53e2517 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -30,7 +30,8 @@ module ActiveRecord
reload
end
- CollectionProxy.create(klass, self)
+ @proxy ||= CollectionProxy.create(klass, self)
+ @proxy.reset_scope
end
# Implements the writer method, e.g. foo.items= for Foo.has_many :items
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 74a4d515c2..8cdb508c43 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -31,6 +31,9 @@ module ActiveRecord
def initialize(klass, association) #:nodoc:
@association = association
super klass, klass.arel_table, klass.predicate_builder
+
+ extensions = association.extensions
+ extend(*extensions) if extensions.any?
end
def target
@@ -1084,9 +1087,8 @@ module ActiveRecord
# person.pets(true) # fetches pets from the database
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
def reload
- @scope = nil
proxy_association.reload
- self
+ reset_scope
end
# Unloads the association. Returns +self+.
@@ -1106,9 +1108,13 @@ module ActiveRecord
# person.pets # fetches pets from the database
# # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
def reset
- @scope = nil
proxy_association.reset
proxy_association.reset_scope
+ reset_scope
+ end
+
+ def reset_scope # :nodoc:
+ @scope = nil
self
end
@@ -1121,19 +1127,6 @@ module ActiveRecord
delegate(*delegate_methods, to: :scope)
- module DelegateExtending # :nodoc:
- private
- def method_missing(method, *args, &block)
- extending_values = association_scope.extending_values
- if extending_values.any? && (extending_values - self.class.included_modules).any?
- self.class.include(*extending_values)
- public_send(method, *args, &block)
- else
- super
- end
- end
- end
-
private
def find_nth_with_limit(index, limit)
@@ -1154,17 +1147,9 @@ module ActiveRecord
@association.find_from_target?
end
- def association_scope
- @association.association_scope
- end
-
def exec_queries
load_target
end
-
- def respond_to_missing?(method, _)
- association_scope.respond_to?(method) || super
- end
end
end
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index d6154c9a38..429f9a257a 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -579,6 +579,10 @@ module ActiveRecord
seed + [self]
end
+ def extensions
+ Array(options[:extend])
+ end
+
protected
def actual_source_reflection # FIXME: this is a horrible name
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index 4f739a0415..dada0fddf8 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -25,8 +25,6 @@ module ActiveRecord
def inherited(child_class)
child_class.initialize_relation_delegate_cache
- delegate = child_class.relation_delegate_class(ActiveRecord::Associations::CollectionProxy)
- delegate.include ActiveRecord::Associations::CollectionProxy::DelegateExtending
super
end
end
diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb
index 029156189d..a61fdd6454 100644
--- a/activerecord/lib/active_record/scoping/named.rb
+++ b/activerecord/lib/active_record/scoping/named.rb
@@ -30,12 +30,15 @@ module ActiveRecord
end
def default_scoped # :nodoc:
- scope = build_default_scope
+ scope = relation
+ build_default_scope(scope) || scope
+ end
- if scope
- relation.spawn.merge!(scope)
+ def default_extensions # :nodoc:
+ if scope = current_scope || build_default_scope
+ scope.extensions
else
- relation
+ []
end
end