aboutsummaryrefslogtreecommitdiffstats
path: root/guides
diff options
context:
space:
mode:
authorNeeraj Singh <neerajdotname@gmail.com>2013-03-08 08:38:43 -0500
committerNeeraj Singh <neerajdotname@gmail.com>2013-03-08 08:38:43 -0500
commit2b8a05f35fbf510907cd133616f45cae120e235f (patch)
treee7b8b6399ca7bf2b1732b7172378b6ea5b80a747 /guides
parentc27f9481dfd1d8196ff727b6f4934892b567bc01 (diff)
downloadrails-2b8a05f35fbf510907cd133616f45cae120e235f.tar.gz
rails-2b8a05f35fbf510907cd133616f45cae120e235f.tar.bz2
rails-2b8a05f35fbf510907cd133616f45cae120e235f.zip
Explained how merging of scope works
Diffstat (limited to 'guides')
-rw-r--r--guides/source/active_record_querying.md56
1 files changed, 56 insertions, 0 deletions
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 575666aafb..da1b4fcbf9 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1196,6 +1196,62 @@ Using a class method is the preferred way to accept arguments for scopes. These
category.posts.created_before(time)
```
+### Merging of scopes
+
+Just like `where` clauses scopes are merged using `AND` conditions.
+
+```ruby
+class User < ActiveRecord::Base
+ scope :active, -> { where state: 'active' }
+ scope :inactive, -> { where state: 'active' }
+end
+
+```ruby
+User.active.inactive
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND "users"."state" = 'inactive'
+```
+
+We can mix and match `scope` and `where` conditions and the final sql
+will have all conditions joined with `AND` .
+
+```ruby
+User.active.where(state: 'finished')
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'active' AND
+"users"."state" = 'finished'
+```
+
+If we do want the `last where clause` to win then `Relation#merge` can
+be used .
+
+```ruby
+User.active.merge(User.inactive)
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
+```
+
+One important caveat is that `default_scope` will be overridden by
+`scope` and `where` conditions.
+
+```ruby
+class User < ActiveRecord::Base
+ default_scope { where state: 'pending' }
+ scope :active, -> { where state: 'active' }
+ scope :inactive, -> { where state: 'active' }
+end
+
+User.all
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
+
+User.active
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
+
+User.where(state: 'inactive')
+# => SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
+```
+
+As you can see above the `default_scope` is being overridden by both
+`scope` and `where` condition.
+
+
### Applying a default scope
If we wish for a scope to be applied across all queries to the model we can use the