aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2011-05-01 16:54:36 -0700
committerDavid Heinemeier Hansson <david@loudthinking.com>2011-05-01 16:54:36 -0700
commit32ef3ccaa6beae4ef73969f51d5159f4cc4d9ff7 (patch)
tree2c6582f2aeadea6e72d362edb95d2cbd7934fb95 /activerecord
parent2db538c8a86d0a15d37d830179bce2452a1531b7 (diff)
parent5164c50d7ff42faa801e827dc8761ff11e61f3e2 (diff)
downloadrails-32ef3ccaa6beae4ef73969f51d5159f4cc4d9ff7.tar.gz
rails-32ef3ccaa6beae4ef73969f51d5159f4cc4d9ff7.tar.bz2
rails-32ef3ccaa6beae4ef73969f51d5159f4cc4d9ff7.zip
Merge pull request #340 from joshk/default_scope_changes.
removed the default_scope deprecations and updated the docs and tests to
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/base.rb53
-rw-r--r--activerecord/test/cases/relation_scoping_test.rb20
-rw-r--r--activerecord/test/models/developer.rb24
3 files changed, 41 insertions, 56 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 04c12f86b6..8d17e3e2c6 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1180,19 +1180,15 @@ MSG
# 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 @@ MSG
# (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 @@ MSG
# 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:
diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb
index 2ed676fe69..864b3d4846 100644
--- a/activerecord/test/cases/relation_scoping_test.rb
+++ b/activerecord/test/cases/relation_scoping_test.rb
@@ -355,6 +355,12 @@ class DefaultScopingTest < ActiveRecord::TestCase
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 @@ class DefaultScopingTest < ActiveRecord::TestCase
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
diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb
index 10701dd6fd..152f804e16 100644
--- a/activerecord/test/models/developer.rb
+++ b/activerecord/test/models/developer.rb
@@ -129,28 +129,40 @@ end
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
+
+