10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ActiveRecord で unscoped を呼ぶとその前のクエリが消える

Posted at

ブログ記事からの転載です。

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"

unscopeddefault_scope を消したい場合は必ず『一番最初』に unscoped を呼び出しましょう。
逆に『レシーバのクエリを全部消したい』場合は unscoped を呼び出すと一括で消すことができるので便利です。

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?