ハコヅミを作る #43:キャンプで作る料理を選ぶと、食材が持ち物チェックに入る
前回(#42)で、料理を登録できるようになりました。今回は、料理をキャンプにつなぎます。
- キャンプで料理を選ぶと、食材が持ち物チェックに入る(#188)
- 選び直したときの、項目の足し引き
- たまに落ちるテストと、止まったデプロイ
キャンプの持ち物=プランの中身+料理の食材
今までは、キャンプの持ち物は、選んだプランの中身でした。ここに、選んだ料理の食材を足します。
食材は消耗品なので、持ち物チェックの消耗品の項目になります。先に決めたことは、次のとおりです。
- 並べ方は、今までどおりコンテナごと。料理ごとには並べない
- プランにも入っている食材、2つの料理で使う食材は、1つの項目にまとめる(数量は足さない)
- 進み具合や、コンテナの一括チェックも、ほかの消耗品と同じに扱う
料理ごとに並べる案もありました。ただ、ハコヅミは、車に積み込む順に並べるアプリです。卵はクーラーボックスに、カレールーはキッチンの箱に入ります。積むときに見たいのは、箱ごとの一覧です。
料理ごとの見え方は、別の場所に作ることにしました。
選んだ時点で、固定する
持ち物チェックの項目は、作った時点のプランの中身で固定しています(#8)。あとでプランを変えても、作ったキャンプは変わりません。
料理も、同じ考えにしました。項目は、料理を選んだ時点の食材で固定する。あとで料理の食材を変えても、作ったキャンプは変わりません。
そのために、「選んだ時点の、料理と食材の組」を持つテーブルを足しています。
| テーブル | 役割 |
|---|---|
camp_dishes |
そのキャンプで作る料理 |
camp_dish_supplies |
料理を選んだ時点の、料理と食材の組 |
もう1つ、今ある項目のテーブルに、列を足しました。「プランから来た項目か」の印です。これが要る理由は、次の話です。
選び直したときの、足し引き
行く前に、料理を変えることがあります。カレーをやめて、鍋にする。このとき、項目をどうするか。
プランを変えたときは、項目を作り直して、チェックを全部外しています(#15)。荷物を最初から見直すためです。
料理は、そうしませんでした。料理を1つ変えただけで、テントのチェックまで外れるのは、やりすぎです。食材の足し引きだけを行い、ほかのチェックは残すことにしました。
足すほうは、単純です。増えた料理の食材のうち、まだ項目にないものを足します。
外すほうが、難しいところでした。カレーを外したとき、玉ねぎの項目を消してよいか。
- 玉ねぎが、プランにも入っているなら、消してはいけない
- 残ったほかの料理でも使うなら、消してはいけない
外すのは、「外した料理の食材のうち、プランから来た項目でなく、残った料理の食材でもないもの」だけです。ここで、さっきの印を使います。
この計算は、画面やデータベースから切り離して、1つの関数にしました。ユニットテストは 26 件あります。料理を入れ替えたとき、両方の料理に入っている食材は、足しも外しもしない(チェックが残る)、といった細かい動きも、ここで確かめています。
画面イメージで、置き場所を選ぶ
キャンプの画面の「料理」
料理ごとの見え方は、キャンプの画面に作ります。置き場所は、3つの案で届きました。

左から、案A(間に置く)、案B(キャンプ情報の中)、案C(持ち物チェックの下)
Claude Code のおすすめは、案A でした。選んだのは、案B です。
料理は、キャンプ場や日付と同じ「このキャンプの情報」です。カードが1つ増えるより、中に入っているほうが、すっきりします。画面の上から「どこに行く、何を作る、何を積む」の順に読めます。
登録の画面の「作る料理」
登録・編集の画面の欄は、おすすめが「プランのすぐ下」でした。持ち物を決める欄を、上にまとめる考えです。
ここは、案にない場所を頼みました。画像の欄の下です。
キャンプを登録するとき、最初に決まっているのは、日付とキャンプ場です。何を作るかは、そのあとで考えます。入力の順番は、考える順番に合わせたいところです。

キャンプの登録の画面。「作る料理」は、一番下に置いた
ついでに、1つ直してもらいました。画像を URL から取り込む欄の名前です。ギアの画面と同じ「または、画像・商品ページの URL」になっていました。キャンプ場に、商品ページはありません。キャンプの画面では「または、画像の URL」にしています。
できあがり

キャンプの画面。料理ごとに、食材がいくつそろったかが分かる
料理の行には、食材がそろった数を出します。全部そろうと、緑で「そろった」と出ます。押すと開いて、食材の名前とレシピが読めます。
食材のない料理は、最初は「食材 0 / 0」と出ていました。意味は合っていますが、読んで分かりません。「食材なし」に変えてもらいました。
E2E が、1回だけ落ちる
PR を作ると、CI の E2E が1つ落ちました。料理とは関係のない、送信の回数の制限のテストです(#35)。
テストは、「1分に 300 回まで」の制限に対して、310 回送って、断られることを確かめていました。落ちたときは、310 回送っても、1回も断られていません。
原因は、数える枠の区切りでした。回数の制限は、1分ごとの枠で数えます。送っている途中で枠が切り替わると、数が 0 に戻ります。前の枠で 200 回、次の枠で 110 回なら、どちらも 300 に届きません。
テストを、次の形に書き直してもらいました。
- 回数を決め打ちにせず、断られるまで送る
- 断られるまでに、300 回以上は通っていること(制限が早すぎない)
- 600 回までには、必ず断られること(枠をまたいでも、2つ分で届く)
「たまに落ちる」テストは、流し直せば通ります。ただ、それで済ませると、次に落ちたときに、本物の失敗と見分けられません。原因が分かるうちに直しました。
デプロイが、始まらない
マージすると、今度はデプロイが止まりました。テストは通っているのに、デプロイのジョブが「待ち」のまま動きません。15 分たつと、キャンセルされます。流し直しても、同じです。
調べてもらうと、原因は GitHub の側でした。GitHub Actions の障害で、ジョブを動かす機械が割り当てられない状態です。15 分は、こちらの設定の上限でした。デプロイが途中で固まったときに、止めるためのものです。
ここで決めたことは、2つです。
- 上限は延ばさない。障害のために延ばすと、本当に固まったときに止まらなくなる
- 手元からはデプロイしない。「反映は、PR のマージから CI で行う」という決まりは、急ぐ理由がないかぎり、破らない
ステップは1つも動いていないので、開発環境は前のデプロイのままです。壊れてはいません。待つことにしました。
障害は、数時間続きました。そのあいだは、コードを書かない相談を進めています。その話は、次回と次々回です。
おわりに
- 並べ方は、使う場面に合わせる。積むときは箱ごと、作るときは料理ごと。1つの一覧で両方を満たそうとしない
- 「あとから変えたとき」を、先に決める。足すより、外すほうが難しい
- ややこしい足し引きは、画面から切り離して、関数とユニットテストにする
- 入力の順番は、考える順番に合わせる
- 時間の区切りに頼るテストは、区切りをまたいでも通る形にする
- 外の障害で止まったときは、守りの設定や決まりを、その場でゆるめない
次回は、止まっているあいだに決めた、フリーと有料の違いです。