Permalink
Browse files

Modified default_scope to merge with any pre-existing default_scope

and added AR::Base::clear_default_scope

- clear_default_scope provides users who rely on the old behaviour
  of each call to default_scope overwriting any previous default
  scopes an opportunity to maintain that behaviour.

[#4583 state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information...
dchelimsky authored and josevalim committed May 14, 2010
1 parent a0621c1 commit 35a114a8941cb22d29a536f1215a23a8cf7c4756
Showing with 34 additions and 3 deletions.
  1. +5 −1 activerecord/lib/active_record/base.rb
  2. +29 −2 activerecord/test/cases/method_scoping_test.rb
@@ -1190,7 +1190,11 @@ def subclasses
# default_scope order('last_name, first_name')
# end
def default_scope(options = {})
- self.default_scoping << construct_finder_arel(options)
+ self.default_scoping << construct_finder_arel(options, default_scoping.pop)
+ end
+
+ def clear_default_scope
+ self.default_scoping.clear
end
def scoped_methods #:nodoc:
@@ -587,6 +587,18 @@ def test_nested_scope
end
end
+class ClearDefaultScopeTest < ActiveRecord::TestCase
+ fixtures :developers
+
+ def test_should_clear_default_scope
+ klass = Class.new(DeveloperCalledDavid)
+ klass.__send__ :clear_default_scope
+ expected = Developer.all.collect { |dev| dev.name }
+ actual = klass.all.collect { |dev| dev.name }
+ assert_equal expected, actual
+ end
+end
+
class DefaultScopingTest < ActiveRecord::TestCase
fixtures :developers, :posts
@@ -615,15 +627,30 @@ def test_default_scoping_with_threads
def test_default_scoping_with_inheritance
# Inherit a class having a default scope and define a new default scope
klass = Class.new(DeveloperOrderedBySalary)
- klass.send :default_scope, {}
+ klass.send :default_scope, :limit => 1
# Scopes added on children should append to parent scope
- assert klass.scoped.order_values.blank?
+ assert_equal 1, klass.scoped.limit_value
+ assert_equal ['salary DESC'], klass.scoped.order_values
# Parent should still have the original scope
+ assert_equal nil, DeveloperOrderedBySalary.scoped.limit_value
assert_equal ['salary DESC'], DeveloperOrderedBySalary.scoped.order_values
end
+ def test_default_scope_called_twice_merges_conditions
+ Developer.destroy_all
+ Developer.create!(:name => "David", :salary => 80000)
+ Developer.create!(:name => "David", :salary => 100000)
+ Developer.create!(:name => "Brian", :salary => 100000)
+
+ klass = Class.new(Developer)
+ klass.__send__ :default_scope, :conditions => { :name => "David" }
+ klass.__send__ :default_scope, :conditions => { :salary => 100000 }
+ assert_equal 1, klass.count
+ assert_equal "David", klass.first.name
+ assert_equal 100000, klass.first.salary
+ end
def test_method_scope
expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary }
received = DeveloperOrderedBySalary.all_ordered_by_name.collect { |dev| dev.salary }

3 comments on commit 35a114a

Contributor

dchelimsky replied May 16, 2010

This was co-authored by Brian Tatnall - his name is in the author field in the commit log, but didn't make it to this page.

Owner

fxn replied May 16, 2010

Yes it is not shown in GitHub, but he is given credit in Rails Contributors at least: http://contributors.rubyonrails.org/contributors/brian-tatnall/commits

vjt replied May 17, 2010

Standing ovation! :-)

Please sign in to comment.