Railsのモデルにdefault_scopeを適用しているプロジェクトはあると思います。
そして、例外的にdefault_scopeを解除したいときもあるはずです。
そんなときは、「unscoped」や「unscope」でdefault_scopeを解除することができます。
この記事ではその方法をご紹介します。
default_scopeとは
default_scopeを使うと、そのモデル全体に絞り込みやorderが適用されます。
下記の例ではArticleというモデルに対して、「published: true」なデータのみ取得します。
class Article < ActiveRecord::Base
default_scope { where(published: true) }
end
Articleに「id:1, published: false」というデータがある場合はデータを取得しない、つまり空配列を返します。
> Article.where(id: 1) SELECT "articles".* FROM "articles" WHERE "articles"."published" = 1 AND "articles"."id" = 1 => #<ActiveRecord::Relation []>
default_scopeを解除する方法
unscoped (全てのクエリを解除)
unscopedを使用することで、default_scopeが解除されます。
> Article.unscoped.where(id: 1) SELECT "articles".* FROM "articles" WHERE "articles"."id" = 1 => #<ActiveRecord::Relation [#<Article id: 1, content: "test", published: false...>]>
しかし、一点注意することがあります。
それはupscopedを使用すると、default_scopeだけでなく、他のクエリも解除されてしまう点です。
下記のようにunscopedの前に付与したwhereも取り除かれてしまいます。
> Article.where(id: 1).unscoped SELECT "articles".* FROM "articles
unscopedの後のクエリは適用されます。
> Article.unscoped.where(id: 1) SELECT "articles".* FROM "articles" WHERE "articles"."id" = 1
そのため、unscopedを使用するタイミングは注意しましょう。
unscope (部分的にクエリを解除)
unscopeはunscopedと異なり、部分的にクエリを解除することができます。
> Article.unscope(where: :published) SELECT "articles".* FROM "articles" => #<ActiveRecord::Relation [#<Article id: 1, content: "test", published: false...>]>
unscopeの前のクエリも適用されます。
> Article.where(id: 1).unscope(where: :published) SELECT "articles".* FROM "articles" WHERE "articles"."id" = 1 => #<ActiveRecord::Relation [#<Article id: 1, content: "test", published: false...>]>
コメント