0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails】find() での ActiveRecord::RecordNotFound エラーと原因について

Last updated at Posted at 2024-11-24

はじめに

記事の内容

  • .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).

実際に表示されたエラー画面
image.png

エラー文 翻訳
"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 だけを検索する」』という処理の流れをしていた

以下が原因だった

  1. 絞ったことで対象の id のレコードが検索対象から外れた
    • 実質的に存在しない id レコード(登録されていないレコード、削除されたレコード)を検索しようとしてしまった
  2. .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 で検索する場合)
image.png

(図2:条件を絞った後に特定の id だけのレコードを where で検索する場合)
image.png

まとめ

  • find() は検索条件の id には必ず存在するレコードの id を指定しなければならない
  • find() は検索条件の id に検索してもヒットしないレコードが 1 件でもある場合はエラーになる
    • ヒットしたレコードだけを返さずエラーとなる
  • where() であれば find() と同じように検索条件に id を指定して該当レコードが見つからない場合であってもエラーにはならない

所感

  • コンソールでは手軽にレコードを検索する際に使用していたため原因になっているとはすぐに気づけなかった
  • ActiveRecord をチェインさせるような検索をする少し複雑な検索をするのであれば find では where を用いた方が良いと学習できた
    • 何を検索条件としているかを明示している分、可読性の面においても良いと思われる

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?