🕌

【Rails】scope内でfind_byを使ってはいけない件

2023/03/22に公開

scope

まずはscopeの公式ドキュメントの引用を読んでみる

scope(name, body, &block)
Adds a class method for retrieving and querying objects.
The method is intended to return an ActiveRecord::Relation object,
which is composable with other scopes.
If it returns nil or false, an all scope is returned instead.
A scope represents a narrowing of a database query,
such as where(color: > :red).select('shirts.*').includes(:washing_instructions).

翻訳:
スコープ(名前、本体、&ブロック)
オブジェクトを取得およびクエリするためのクラス メソッドを追加します。
このメソッドは、ActiveRecord::Relation オブジェクトを返すことを目的としています。
これは他のスコープと構成可能です。
nil または false を返す場合は、代わりに all スコープが返されます。
スコープは、データベース クエリの絞り込みを表します。
where(color: > :red).select('Shirts.*').includes(:washing_instructions) など。

find_byを使うとどうなる

そもそもでいうと、ActiveRecord::Relation オブジェクトを返すことを目的としているのでこの時点で使い方は間違っているのだが、、、
仮に、それを無視して使った場合、何が怖いかと言うと、ドキュメントにある通り
nilまたはfalseが返り値になる場合、all(SELECT table_names.* FROM table_names)が実行されるという挙動になるようです。

find_byで見つからなかった場合allが返ってくるって結構怖い挙動ですよね笑

まとめ

普段何気なく使っていると、(使い慣れすぎると)、逆に「この使い方いけるのかな?」なんて疑問が湧いてきますが、やっぱり見慣れない方法は使わないにこしたことはないなと思いました。

Discussion