ブログ記事からの転載です。
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
を呼び出すと一括で消すことができるので便利です。