症状
Rails6.0.3でcontrollerからDBに対して、findでデータを取りに行ったとき、下記エラーメッセージが出てしまいました。humans_controller#show
def show
classroom_id = Classroom.find_by(id: params[:classroomId])
human = Human.find_by(id: params[:id],classroom_id: classroom_id)
render json: {
human: human
}, status: :ok
end
findでエラー
app/controllers/api/v1/foods_controller.rb:26:in `show'
Started GET "/api/v1/classroom/1/human/2" for ::1 at 2021-05-02 00:16:30 +0900
(0.1ms) SELECT sqlite_version(*)
Processing by Api::V1::HumansController#show as HTML
Parameters: {"classroom_id"=>"1", "id"=>"2"}
Restaurant Load (0.3ms) SELECT "classrooms".* FROM "classrooms" WHERE "classroom"."id" = ? LIMIT ?
[["id", nil], ["LIMIT", 1]]
↳ app/controllers/api/v1/humans_controller.rb:26:in `show'
Completed 404 Not Found in 174ms (ActiveRecord: 1.9ms | Allocations: 2232)
ActiveRecord::RecordNotFound (Couldn't find Classroom with 'id'={:id=>nil}):
下記記事で同様のエラーメッセージを発見。
【Rails】find・find_by・whereについてまとめてみた
そこには主キーが見つからない場合、上記のActiveRecord::RecordNotFoundと怒られる模様。
解決策
findをfind_byに変更したら、解決しました。findだと、主キーに対してのみ条件づけするので、find(id)と書けます。
が、find(id: id)とは書けないため、idにnilが入ってしまい、結果として、主キーに該当するデータがないと怒られていたようです。
find
#できる
id = 1
human = human.find(id)
#できない
human = human.find(id: 1)
find_byだと、主キー以外にも条件づけできるので、カラム名を指定する必要があります。
なので、下記のように条件づけるカラム名も一緒にしてできます。
find_by
#できる
human = human.find(id: 1)
#できる
human = human.find_by(name: "太郎")