aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/scoping
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2015-02-11 13:40:28 -0700
committerSean Griffin <sean@thoughtbot.com>2015-02-11 13:46:30 -0700
commit5e0b555b453ea2ca36986c111512627d806101e7 (patch)
tree20db60dde260daf1bbc85cf00c8c5de7bf50bb7b /activerecord/lib/active_record/scoping
parent42d62de0007b4b4813adc2eb27c3a83e57018ac4 (diff)
downloadrails-5e0b555b453ea2ca36986c111512627d806101e7.tar.gz
rails-5e0b555b453ea2ca36986c111512627d806101e7.tar.bz2
rails-5e0b555b453ea2ca36986c111512627d806101e7.zip
`current_scope` shouldn't pollute sibling STI classes
It looks like the only reason `current_scope` was thread local on `base_class` instead of `self` is to ensure that when we call a named scope created with a proc on the parent class, it correctly uses the default scope of the subclass. The reason this wasn't happening was because the proc captured `self` as the parent class, and we're not actually defining a real method. Using `instance_exec` fixes the problem. Fixes #18806
Diffstat (limited to 'activerecord/lib/active_record/scoping')
-rw-r--r--activerecord/lib/active_record/scoping/named.rb17
1 files changed, 13 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/scoping/named.rb b/activerecord/lib/active_record/scoping/named.rb
index a083deafe1..43c7b1c574 100644
--- a/activerecord/lib/active_record/scoping/named.rb
+++ b/activerecord/lib/active_record/scoping/named.rb
@@ -157,11 +157,20 @@ module ActiveRecord
extension = Module.new(&block) if block
- singleton_class.send(:define_method, name) do |*args|
- scope = all.scoping { body.call(*args) }
- scope = scope.extending(extension) if extension
+ if body.respond_to?(:to_proc)
+ singleton_class.send(:define_method, name) do |*args|
+ scope = all.scoping { instance_exec(*args, &body) }
+ scope = scope.extending(extension) if extension
- scope || all
+ scope || all
+ end
+ else
+ singleton_class.send(:define_method, name) do |*args|
+ scope = all.scoping { body.call(*args) }
+ scope = scope.extending(extension) if extension
+
+ scope || all
+ end
end
end
end