https://rails-bestpractices.com/posts/2013/06/15/default_scope-is-evil/
偉大な本家様
自分の勉強用に Rails Best Practiceシリーズを翻訳します。
今まで何度もdefault_scopeを使ってきましたが、後になって後悔しました。
Postモデルでdefault_scopeを定義したとします。
class Post
default_scope where(published: true).order("created_at desc")
end
default_scope は、期待していないいくつかの動作を追加します。
1. デフォルトのスコープを上書きすることはできません。
例えば、デフォルトでは、postsを created_at の順に表示します。
> Post.limit(10)
Post Load (3.3ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`published` = 1 ORDER BY created_at desc LIMIT 10
created_atではなくupdated_atの順にpostsを表示したい場合は、次の行を使用します、
> Post.order("updated_at desc").limit(10)
Post Load (17.3ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`published` = 1 ORDER BY created_at desc, updated_at desc LIMIT 10
しかし、ご覧のように created_at と updated_at の両方で並び順を決めているので、デフォルトのスコープは上書きされません。
> Post.unscoped.order("updated_at desc").limit(10)
Post Load (1.9ms) SELECT `posts`.* FROM `posts` ORDER BY updated_at desc LIMIT 10
モデルにはdefault_scopeがあることを覚えておいて、デフォルトのスコープをオーバーライドしたい場合はunscopedを追加しなければなりません。
2. default_scopeはモデルの初期化に影響します。たとえば、
> Post.new
=> #<Post id: nil, title: nil, created_at: nil, updated_at: nil, user_id: nil, published: true>
most developers are not aware this point, they think default_scope only affect queries, it is the wrong way default_scope does.
ほとんどの開発者はこの点を認識していない。default_scopeがクエリにのみ影響を与えると思っているが、そうではなくクエリ以外にも影響を与える。
default_scope はもう使わないで、スコープとして定義して、そのスコープを明示的に呼び出すようにしましょう。
コメント