回答:
基本的な例を考えてみましょう:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
デフォルトにする動機は、published: true
非公開(非公開)投稿を表示したいときに明示する必要があることを確認することです。ここまでは順調ですね。
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
まあこれは私たちが期待するものとほとんど同じです。今試してみましょう:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
そして、デフォルトのスコープに最初の大きな問題があります:
=> default_scopeはモデルの初期化に影響します
そのようなモデルの新しく作成されたインスタンスでは、default_scope
が反映されます。そのため、未公開の投稿を偶然にリストしないようにしたかったかもしれませんが、現在はデフォルトで公開済みの投稿を作成しています。
より複雑な例を考えてみましょう:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
最初のユーザーの投稿を取得できます:
2.1.1 :001 > User.first.posts
Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't' AND "posts"."user_id" = ? [["user_id", 1]]
これは予想通りです(user_idに関する部分を表示するには、右端までスクロールしてください)。
ここで、すべての投稿のリストを取得したい-非公開が含まれている-ログインしたユーザーのビューについて言ってください。の効果を「上書き」または「元に戻す」必要があることに気付くでしょうdefault_scope
。簡単なグーグルの後、あなたはおそらくについて知るでしょうunscoped
。次に何が起こるかを見てください:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=>スコープなしでは、通常、選択に適用される可能性のあるすべてのスコープが削除されます。
のさまざまな効果を上書きする方法は複数ありますdefault_scope
。これを正しく行うことは非常に迅速に複雑にdefault_scope
なります。そもそもを使用しない方が安全な選択だと私は主張します。
unscoped
ではなく問題であるようですdefault_scope
default_scope
何かをソートしたいときは、次のように使うのがいいと思います:default_scope { order(:name) }
。
未使用のもう一つの理由は、default_scope
あなたが持つ多くの関係を1持っているモデルのインスタンスを削除しているときであるdefault_scope
モデルを
例を考えてみましょう:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
を呼び出すuser.destroy
と、の投稿はすべて削除されますが、の投稿published
は削除されませんunpublished
。したがって、データベースには、削除するユーザーを参照するレコードが含まれているため、外部キー違反がスローされます。