diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2017-09-04 03:51:24 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2017-09-04 03:51:24 +0900 |
commit | 925e6d561ae8847777e57f6a0bacc930d35bf05b (patch) | |
tree | 9bcbeb237f9593dd352172dbcc6350ac300851ee | |
parent | 6a099b168216db45be2d95aa51eac62100b62058 (diff) | |
download | rails-925e6d561ae8847777e57f6a0bacc930d35bf05b.tar.gz rails-925e6d561ae8847777e57f6a0bacc930d35bf05b.tar.bz2 rails-925e6d561ae8847777e57f6a0bacc930d35bf05b.zip |
Scope in associations should treat nil as `all`
Defined scope treats nil as `all`, but scope in associations isn't so.
If the result of the scope is nil, most features on associations will be
broken. It should treat nil as `all` like defined scope.
Fixes #20823.
6 files changed, 11 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb index 268b022ab8..ca1f9f1650 100644 --- a/activerecord/lib/active_record/associations/association.rb +++ b/activerecord/lib/active_record/associations/association.rb @@ -130,8 +130,8 @@ module ActiveRecord def extensions extensions = klass.default_extensions | reflection.extensions - if scope = reflection.scope - extensions |= klass.unscoped.instance_exec(owner, &scope).extensions + if reflection.scope + extensions |= reflection.scope_for(klass.unscoped, owner).extensions end extensions diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb index 3d79e540b8..e790bd3db9 100644 --- a/activerecord/lib/active_record/associations/association_scope.rb +++ b/activerecord/lib/active_record/associations/association_scope.rb @@ -174,7 +174,8 @@ module ActiveRecord end def eval_scope(reflection, table, scope, owner) - reflection.build_scope(table).instance_exec(owner, &scope) + relation = reflection.build_scope(table) + relation.instance_exec(owner, &scope) || relation end end end diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb index ac37c3c015..77b3d11b47 100644 --- a/activerecord/lib/active_record/associations/join_dependency.rb +++ b/activerecord/lib/active_record/associations/join_dependency.rb @@ -256,7 +256,8 @@ module ActiveRecord else model = construct_model(ar_parent, node, row, model_cache, id, aliases) - if node.reflection.scope_for(node.base_klass).readonly_value + if node.reflection.scope && + node.reflection.scope_for(node.base_klass.unscoped).readonly_value model.readonly! end diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb index 4915a37f06..3fa97af759 100644 --- a/activerecord/lib/active_record/associations/preloader/association.rb +++ b/activerecord/lib/active_record/associations/preloader/association.rb @@ -113,7 +113,7 @@ module ActiveRecord end def reflection_scope - @reflection_scope ||= reflection.scope_for(klass) + @reflection_scope ||= reflection.scope ? reflection.scope_for(klass.unscoped) : klass.unscoped end def build_scope diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 00ff20f4d7..49ddcaecdf 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -214,7 +214,7 @@ module ActiveRecord def join_scopes(table, predicate_builder) # :nodoc: if scope - [build_scope(table, predicate_builder).instance_exec(&scope)] + [scope_for(build_scope(table, predicate_builder))] else [] end @@ -391,8 +391,8 @@ module ActiveRecord active_record == other_aggregation.active_record end - def scope_for(klass) - scope ? klass.unscoped.instance_exec(nil, &scope) : klass.unscoped + def scope_for(relation, owner = nil) + relation.instance_exec(owner, &scope) || relation end private diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb index 025d013fb4..0a52cc5390 100644 --- a/activerecord/test/models/author.rb +++ b/activerecord/test/models/author.rb @@ -78,7 +78,7 @@ class Author < ActiveRecord::Base after_add: [:log_after_adding, Proc.new { |o, r| o.post_log << "after_adding_proc#{r.id || '<new>'}" }] has_many :unchangeable_posts, class_name: "Post", before_add: :raise_exception, after_add: :log_after_adding - has_many :categorizations + has_many :categorizations, -> {} has_many :categories, through: :categorizations has_many :named_categories, through: :categorizations |