Beware of using default scope
Default Scope is used to apply scope to all queries by default.
class User < ActiveRecord::Base
default_scope {where(state: 'pending')}
end
User.all #=> User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."status" = 'pending'
Lets add one more scope
class User < ActiveRecord::Base
default_scope {where(state: 'pending')}
scope :active, ->{where(state: 'active')}
end
User.active #=> SELECT "users".* FROM "users" WHERE "users"."status" = 'pending' AND "users"."status" = 'active'
User.where(state: 'active') #=> SELECT "users".* FROM "users" WHERE "users"."status" = 'pending' AND "users"."status" = 'active'
As you can see It hasn't override default scope
which we thought it should because we are scoping on same column
So if you have default scope
and want to remove default scope behaviour from other scope you can user unscope
, unscoped
or rewhere
and except
class User < ActiveRecord::Base
default_scope {where(state: 'pending')}
scope :active, ->{unscope(where: :state).where(state: 'active')}
end
class User < ActiveRecord::Base
default_scope {where(state: 'pending')}
scope :active, ->{where(state: 'active')}
end
User.unscoped.active #=> SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
User.rewhere(state: 'active') #=> SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
User.except(:default_scope).active #=> SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
You can find more detail here
https://github.com/rails/rails/issues/13875#issuecomment-35430595
So Beware of using Default Scope
.
Written by Rashmi
Related protips
3 Responses
Creating new objects will have a pending state too.
over 1 year ago
·
true
over 1 year ago
·
Ya both can have their specific default scope
over 1 year ago
·
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Rails
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#