ベストアンサー1
問題1
基本的な例を考えてみましょう:
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
反映されます。そのため、未公開の投稿が誤ってリストされないようにしたいかもしれませんが、デフォルトで公開済みの投稿が作成されます。
問題2
より複雑な例を考えてみましょう。
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
簡単に Google で検索すると、 について見つかるでしょうunscoped
。 次に何が起こるか見てみましょう。
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Unscoped は、関連付けを含む (ただしこれに限定されない)、通常、選択に適用される可能性のあるすべてのスコープを削除します。
のさまざまな効果を上書きする方法は複数ありますdefault_scope
。それを正しく行うことで複雑default_scope
非常に迅速に、そして最初から使用しない方がより安全な選択であると私は主張します。