From 5164c50d7ff42faa801e827dc8761ff11e61f3e2 Mon Sep 17 00:00:00 2001 From: Josh Kalderimis Date: Thu, 28 Apr 2011 18:46:26 +0200 Subject: removed the default_scope deprecations and updated the docs and tests to reflect its use cases --- activerecord/lib/active_record/base.rb | 53 ++++++++---------------- activerecord/test/cases/relation_scoping_test.rb | 20 +++------ activerecord/test/models/developer.rb | 24 ++++++++--- 3 files changed, 41 insertions(+), 56 deletions(-) (limited to 'activerecord') 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 default_scope 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 call to the default_scope # macro, and it will be called when building the default scope.) # + # If you use multiple default_scope 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 default_scope 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 + + -- cgit v1.2.3