From 6370e69143b5edce1b61135259e1f81006aaee6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 18 Feb 2014 12:04:26 -0300 Subject: Document the default scopes change on the release notes, CHANGELOG and upgrating guides [ci skip] --- guides/source/upgrading_ruby_on_rails.md | 67 ++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'guides/source/upgrading_ruby_on_rails.md') diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 8aae3bbc1a..74cfa23649 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -262,6 +262,73 @@ authors = Author.where(name: 'Hank Moody').to_a authors.compact! ``` +### Changes on Default Scopes + +Default scopes are no longer overriden by chained conditions. + +In previous versions when you defined a `default_scope` in a model +it was overriden by chained conditions in the same field. Now it +is merged like any other scope. + +Before: + +```ruby +class User < ActiveRecord::Base + default_scope { where state: 'pending' } + scope :active, -> { where state: 'active' } + scope :inactive, -> { where state: 'inactive' } +end + +User.all +# => SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' + +User.active +# => SELECT "users".* FROM "users" WHERE "users"."status" = 'active' + +User.where(state: 'inactive') +# => SELECT "users".* FROM "users" WHERE "users"."status" = 'inactive' +``` + +After: + +```ruby +class User < ActiveRecord::Base + default_scope { where state: 'pending' } + scope :active, -> { where state: 'active' } + scope :inactive, -> { where state: 'inactive' } +end + +User.all +# => SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' + +User.active +# => SELECT "users".* FROM "users" WHERE "users"."status" = 'pending' AND "users"."status" = 'active' + +User.where(state: 'inactive') +# => SELECT "users".* FROM "users" WHERE "users"."status" = 'pending' AND "users"."status" = 'inactive' +``` + +To get the previous behavior it is needed to explicitly remove the +`default_scope` condition using `unscoped`, `unscope`, `rewhere` or +`except`. + +```ruby +class User < ActiveRecord::Base + default_scope { where state: 'pending' } + scope :active, -> { unescope(where: :state).where(state: 'active') } + scope :inactive, -> { rewhere state: 'inactive' } +end + +User.all +# => SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' + +User.active +# => SELECT "users".* FROM "users" WHERE "users"."status" = 'active' + +User.inactive +# => SELECT "users".* FROM "users" WHERE "users"."status" = 'inactive' +``` + Upgrading from Rails 3.2 to Rails 4.0 ------------------------------------- -- cgit v1.2.3