ブログ記事からの転載です。
unscoped を使うことで default_scope を取り除くことができる
さて、皆さん大好き default_scope ですが、モデルで default_scope を定義すると次のように暗黙的にクエリが追加されます。
class User < ActiveRecord::Base
default_scope { order(:updated_at) }
end
# 暗黙的に ORDER BY のクエリが追加れる
puts User.all.to_sql
# => SELECT "users".* FROM "users" ORDER BY "users"."updated_at" ASC
puts User.where(name: "Tom").to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" = 'Tom' ORDER BY "users"."updated_at" ASC
毎回 order(:updated_at) する必要がないので便利ですね。
でも『あ〜今日は default_scope のクエリ追加してほしくないな〜〜〜』って思うときがあると思うんですよ。
そういう時に unscoped を使うと default_scope のクエリを取り除く事ができます。
# unscoped を付けると default_scope はつかなくなる
puts User.unscoped.all.to_sql
# => SELECT "users".* FROM "users"
puts User.unscoped.where(name: "Tom").to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" = 'Tom'
これで default_scope をつかっていてもシュッと取り除く事ができて便利ですね!
default_scope 以外のクエリも取り除かれる
unscoped を使うことで default_scope を取り除く事ができるようになります。
しかし unscoped はめちゃくちゃ強くて『呼び出すよりも前のリレーション』も取り除いてしまします。
# unscoped よりも前に付けた where のクエリも消してしまう
puts User.where(name: "Tom").unscoped.to_sql
# => SELECT "users".* FROM "users"
unscoped で default_scope を消したい場合は必ず『一番最初』に unscoped を呼び出しましょう。
逆に『レシーバのクエリを全部消したい』場合は unscoped を呼び出すと一括で消すことができるので便利です。