Railsのdefault_scopeは使うな、絶対(翻訳)

概要 原著者の許諾を得て翻訳・公開いたします。 英語記事: Don’t use default_scope. Ever. 公開日: 2017/10/01 著者: Andy Croll — フリーランスのRuby開発者です。 Railsのdefault_scopeは使うな、絶対(翻訳) あるモデル全体にスコープを適用したい場合、default_scopeが利用できます。詳しくはRailsガイド: Active Recordクエリインターフェイス 14.スコープ(日本語)かRailsドキュメントをご覧ください。 投稿を非表示にできる機能を持つブログシステムを書き始めるときを考えてみます。 次のように書かないこと default_scopeを使う: # app/models/post.rb class Post < ActiveRecord::Base default_scope { where(hidden: false) } end 次のように書くこと 明示的にスコープを指定する: # app/models/post.rb class Post < ActiveRecord::Base scope, :published -> { where(hidden: false) } end これで次のように書けます。 Post.published なぜdefault_scopeがだめなのか 理由は2つあります。どちらも後になってコードが混乱したりバグつぶしに明け暮れたりすることを避けるのが目的です。 default_scopeを追加すると、モデルの初期化が影響を受けます。上の例で言うと、開発者が期待するかどうかにかかわらずPost.newするとデフォルトでhidden = falseになってしまいます。 いったん定義されたdefault_scopeを使わないようにするのは大変です。default_scopeが不要な場面で削除するには、unscopedしたスコープ(!)を使わなければならず、しかも適用されていた関連付けなどの条件はすべて削除されてしまいます。 例: Post.first.comments.unscopedとすると、Postの最初のコメントだけではなく、データベース内のすべてのコメントを返します。 default_scopeより明確な解決法は、明示的な名前付きスコープを使うことです。default_scopeを使えばバグつぶしに何時間も費やすことになるでしょう。default_scopeは使わないでください。 default_scopeを使ってもよさそうな場面はありますか? どうかこればかりは私を信じてください。使えばきっと痛い目にあいます。 関連記事 よくある?Rails失敗談 default_scope編 論理削除用paranoia gemがあるRailsプロジェクトで物理削除する方法