14 Scopes
Scoping allows you to specify commonly-used queries which can be referenced as method calls on the association objects or models.
class User < ActiveRecord::Base
scope :active, -> { where(status: 'active') }
end
class User < ActiveRecord::Base
def self.active
where(status: 'active')
end
end
どちらの定義も同様のもの。
scopeはおおよそクラスメソッドのように利用する。
User.active
# => SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
One important caveat is that default_scope will be overridden by scope and where conditions.
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"."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 conditions.
default_scopeはscopeにも、whereによっても無効になる。
14.3 Applying a default scope
If we wish for a scope to be applied across all queries to the model we can use the default_scope method within the model itself.
class Client < ActiveRecord::Base
default_scope { where("removed_at IS NULL") }
end
When queries are executed on this model, the SQL query will now look something like this:
SELECT * FROM clients WHERE removed_at IS NULL
If you need to do more complex things with a default scope, you can alternatively define it as a class method:
class Client < ActiveRecord::Base
def self.default_scope
# Should return an ActiveRecord::Relation.
end
end
モデルのすべてのクエリに対してscopeを適用したいときはdefault_scope
を定義する。
self.default_scope
でも同様の効果。