Skip to content
Browse files

Merge pull request #340 from joshk/default_scope_changes.

removed the default_scope deprecations and updated the docs and tests to
  • Loading branch information...
2 parents 2db538c + 5164c50 commit 32ef3ccaa6beae4ef73969f51d5159f4cc4d9ff7 @dhh dhh committed May 1, 2011
View
53 activerecord/lib/active_record/base.rb
@@ -1180,19 +1180,15 @@ def current_scope=(scope) #:nodoc:
# Use this macro in your model to set a default scope for all operations on
# the model.
#
- # class Person < ActiveRecord::Base
- # default_scope order('last_name, first_name')
+ # class Article < ActiveRecord::Base
+ # default_scope where(:published => true)
# end
#
- # Person.all # => SELECT * FROM people ORDER BY last_name, first_name
+ # Article.all # => SELECT * FROM articles WHERE published = true
#
# The <tt>default_scope</tt> is also applied while creating/building a record. It is not
# applied while updating a record.
#
- # class Article < ActiveRecord::Base
- # default_scope where(:published => true)
- # end
- #
# Article.new.published # => true
# Article.create.published # => true
#
@@ -1205,6 +1201,19 @@ def current_scope=(scope) #:nodoc:
# (You can also pass any object which responds to <tt>call</tt> to the <tt>default_scope</tt>
# macro, and it will be called when building the default scope.)
#
+ # If you use multiple <tt>default_scope</tt> declarations in your model then they will
+ # be merged together:
+ #
+ # class Article < ActiveRecord::Base
+ # default_scope where(:published => true)
+ # default_scope where(:rating => 'G')
+ # end
+ #
+ # Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
+ #
+ # This is also the case with inheritance and module includes where the parent or module
+ # defines a <tt>default_scope</tt> and the child or including class defines a second one.
+ #
# If you need to do more complex things with a default scope, you can alternatively
# define it as a class method:
#
@@ -1214,36 +1223,8 @@ def current_scope=(scope) #:nodoc:
# end
# end
def default_scope(scope = {})
- if default_scopes.length != 0
- ActiveSupport::Deprecation.warn <<-WARN
-Calling 'default_scope' multiple times in a class (including when a superclass calls 'default_scope') is deprecated. The current behavior is that this will merge the default scopes together:
-
-class Post < ActiveRecord::Base # Rails 3.1
- default_scope where(:published => true)
- default_scope where(:hidden => false)
- # The default scope is now: where(:published => true, :hidden => false)
-end
-
-In Rails 3.2, the behavior will be changed to overwrite previous scopes:
-
-class Post < ActiveRecord::Base # Rails 3.2
- default_scope where(:published => true)
- default_scope where(:hidden => false)
- # The default scope is now: where(:hidden => false)
-end
-
-If you wish to merge default scopes in special ways, it is recommended to define your default scope as a class method and use the standard techniques for sharing code (inheritance, mixins, etc.):
-
-class Post < ActiveRecord::Base
- def self.default_scope
- where(:published => true).where(:hidden => false)
- end
-end
- WARN
- end
-
scope = Proc.new if block_given?
- self.default_scopes = default_scopes.dup << scope
+ self.default_scopes = default_scopes + [scope]
end
def build_default_scope #:nodoc:
View
20 activerecord/test/cases/relation_scoping_test.rb
@@ -355,6 +355,12 @@ def test_default_scope_with_inheritance
assert_equal 50000, wheres[:salary]
end
+ def test_default_scope_with_module_includes
+ wheres = ModuleIncludedPoorDeveloperCalledJamis.scoped.where_values_hash
+ assert_equal "Jamis", wheres[:name]
+ assert_equal 50000, wheres[:salary]
+ end
+
def test_default_scope_with_multiple_calls
wheres = MultiplePoorDeveloperCalledJamis.scoped.where_values_hash
assert_equal "Jamis", wheres[:name]
@@ -456,18 +462,4 @@ def test_unscoped_with_named_scope_should_not_have_default_scope
assert DeveloperCalledJamis.unscoped.poor.include?(developers(:david).becomes(DeveloperCalledJamis))
assert_equal 10, DeveloperCalledJamis.unscoped.poor.length
end
-
- def test_multiple_default_scope_calls_are_deprecated
- klass = Class.new(ActiveRecord::Base)
-
- assert_not_deprecated do
- klass.send(:default_scope, :foo => :bar)
- end
-
- assert_deprecated do
- klass.send(:default_scope, :foo => :bar)
- end
-
- assert_equal 2, klass.default_scopes.length
- end
end
View
24 activerecord/test/models/developer.rb
@@ -129,28 +129,40 @@ def self.default_scope
class DeveloperCalledJamis < ActiveRecord::Base
self.table_name = 'developers'
+
default_scope where(:name => 'Jamis')
scope :poor, where('salary < 150000')
end
class PoorDeveloperCalledJamis < ActiveRecord::Base
self.table_name = 'developers'
+
default_scope where(:name => 'Jamis', :salary => 50000)
end
class InheritedPoorDeveloperCalledJamis < DeveloperCalledJamis
self.table_name = 'developers'
- ActiveSupport::Deprecation.silence do
- default_scope where(:salary => 50000)
- end
+ default_scope where(:salary => 50000)
end
class MultiplePoorDeveloperCalledJamis < ActiveRecord::Base
self.table_name = 'developers'
+
default_scope where(:name => 'Jamis')
+ default_scope where(:salary => 50000)
+end
- ActiveSupport::Deprecation.silence do
- default_scope where(:salary => 50000)
- end
+module SalaryDefaultScope
+ extend ActiveSupport::Concern
+
+ included { default_scope where(:salary => 50000) }
end
+
+class ModuleIncludedPoorDeveloperCalledJamis < DeveloperCalledJamis
+ self.table_name = 'developers'
+
+ include SalaryDefaultScope
+end
+
+

0 comments on commit 32ef3cc

Please sign in to comment.
Something went wrong with that request. Please try again.