はじめに
記事の内容
-
.find()
を用いてレコードを取得しようとする際の注意点について -
ActiveRecord::RecordNotFound
エラーの原因について
対象者
- 同じようなエラーに出くわした方
エラーが出た箇所とエラー文について
エラー箇所について
order_likes_ary = PostLike.group(:post_id).order('count(post_id) desc').pluck(:post_id)
@good_posts = published_posts.find(order_likes_ary).in_order_of(:id, order_likes_ary)
実際のエラー
ActiveRecord::RecordNotFound at /
Couldn't find all Posts with 'id': (86, 103, 104, 140, 114, 102, 116, 129, 143, 98, 145, 99)
[WHERE "posts"."draft_flg" = $1] (found 11 results, but was looking for 12).
エラー文 | 翻訳 |
---|---|
"Couldn't find all Posts with 'id'" | 'id' の投稿がすべて見つかりませんでした |
"found 11 results, but was looking for 12" | 11 件の結果が見つかりましたが、12 件を探していました |
- 検索条件で指定している "id" が原因と分かる
- 11件は検索結果として見つかっているのにエラーとなっている
- 「12件を探していました」というのがポイント?
結論
-
find()
で引数に検索条件の "id" の配列に該当する 全てのレコードが取得できない ためエラーとなっている- 全て取得する必要があるため 1 つでもヒットしない場合はエラーになる
If one or more records cannot be found for the requested ids, then ActiveRecord::RecordNotFound will be raised.
「要求された ID に対して 1 つ以上のレコードが見つからない場合、ActiveRecord::RecordNotFound が発生します。」
(引用:https://api.rubyonrails.org/v8.0/classes/ActiveRecord/FinderMethods.html#method-i-find)
詳細
今回私は以下の図のように
『「 publish_flg というフラグカラムが 1 のレコードに絞る」 → 「その中から対象の id だけを検索する」』という処理の流れをしていた
以下が原因だった
- 絞ったことで対象の id のレコードが検索対象から外れた
- 実質的に存在しない id レコード(登録されていないレコード、削除されたレコード)を検索しようとしてしまった
-
.find()
は.where()
とは異なり検索結果のレコードが無い場合はエラーを返す- ヒットしたレコードだけを返すわけでは無い
- この場合は
.where()
の方が良かった
# 修正前
published_posts.find(order_likes_ary).in_order_of(:id, order_likes_ary)
# 修正後
published_posts.where(id: order_likes_ary).in_order_of(:id, order_likes_ary)
(図1:条件を絞った後に特定の id だけのレコードを find
で検索する場合)
(図2:条件を絞った後に特定の id だけのレコードを where
で検索する場合)
まとめ
-
find()
は検索条件の id には必ず存在するレコードの id を指定しなければならない -
find()
は検索条件の id に検索してもヒットしないレコードが 1 件でもある場合はエラーになる- ヒットしたレコードだけを返さずエラーとなる
-
where()
であればfind()
と同じように検索条件にid
を指定して該当レコードが見つからない場合であってもエラーにはならない
所感
- コンソールでは手軽にレコードを検索する際に使用していたため原因になっているとはすぐに気づけなかった
- ActiveRecord をチェインさせるような検索をする少し複雑な検索をするのであれば
find
ではwhere
を用いた方が良いと学習できた- 何を検索条件としているかを明示している分、可読性の面においても良いと思われる
参考資料