Escopo padrão é usado para aplicar o escopo a todas as consultas por padrão.
class User < ActiveRecord::Base
default_scope {where(state: 'pending')}
end
User.all #=> User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."status" = 'pending'
Vamos adicionar mais um escopo
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'
Como você pode ver, ele não substituiu o default scope
que pensávamos que deveria, porque estamos definindo o escopo na mesma coluna
Então, se você tem default scope
e deseja remover o comportamento do escopo padrão de outro escopo, você pode usar unscope
, unscoped
ou rewhere
eexcept
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'
Você pode encontrar mais detalhes aqui
https://github.com/rails/rails/issues/13875#issuecomment-35430595
Portanto, cuidado com o uso Default Scope
.