motohiro-mm / GohanSummit

自作サービス
0 stars 0 forks source link

リソース設計をする #34

Closed motohiro-mm closed 1 month ago

motohiro-mm commented 2 months ago

エレベーターピッチ https://bootcamp.fjord.jp/products/20181

ペーパープロトタイプ https://bootcamp.fjord.jp/products/20557

DB設計 https://github.com/motohiro-mm/MenuDiscussionBoard/issues/5

motohiro-mm commented 1 month ago
初回案 |Mehod|Path|Description| |--|--|--| |GET | / | 未ログイン時トップページ| |GET | /auth/:provider/callback | omniauthでのログイン処理| |DELETE | /logout | ログアウト実行| |DELETE | /retirement | アカウント削除実行| |GET | /meals | 週ごとの献立一覧(ログイン後トップページ)| |GET | /meals/calendar | 月毎の献立一覧| |GET | /meals/:id | 献立詳細画面| |GET | /meals/new | 献立新規登録画面| |POST | /meals | 献立を新規登録する| |GET | /meals/:id/edit | 献立の編集画面| |PUT | /meals/:id | 献立を更新する| |DELETE | /meals/:id | 献立を削除する| |GET | /meals/:id/remarks | 献立ごとの意見一覧画面(相談部屋トップ画面)| |GET | /meals/:id/remarks/new | 意見の新規登録画面| |POST | /meals/:id/remarks | 意見を新規登録する| |GET | /meals/:id/remarks/:id/edit | 意見の編集画面| |PUT | /meals/:id/remarks/:id | 意見を更新する| |DELETE | /meals/:id/remarks/:id | 意見を削除する| |GET | /meals/:id/remarks/:id/timing | 食事メニュー決定画面(朝昼夜を選ぶ)| |POST | /meals/:id/remarks/:id/timing | 意見(提案)を食事メニューに登録する| |GET | /meals/:id/remarks/:id/done | 意見(提案)を食事メニューに登録完了した画面| |GET | /user | ユーザー設定画面| |PUT | /user | ユーザー設定を更新する| |GET | /menu | 献立表の共有画面| |GET | /welcome?invitation_token=....... | 招待されたときのURL| |GET | /about | 使い方| |GET | /terms | 利用規約| |GET | /privacy | プライパシーポリシー|

ボツ理由: mealがないとremarkが作成できない remarkのために全日付に事前にmealを作成しないといけなくなってしまう

motohiro-mm commented 1 month ago
Method Path Description
GET / 未ログイン時トップページ
GET /auth/:provider/callback omniauthでのログイン処理
DELETE /logout ログアウト実行
DELETE /retirement アカウント削除実行
GET /meal_plans 週ごとの献立一覧(ログイン後トップページ)
GET /meal_plans/calendar 月毎の献立一覧
GET /meal_plans/:id 献立詳細画面
GET /meal_plans/new 献立新規登録画面
POST /meal_plans 献立を新規登録する
GET /meal_plans/:id/edit 献立の編集画面
PUT /meal_plans/:id 献立を更新する
POST /meeting_rooms 相談部屋を作成する
GET /meeting_rooms/:id 献立ごとの意見一覧画面(相談部屋トップ画面)
GET /meeting_rooms/:id/remarks/new 意見の新規登録画面
POST /meeting_rooms/:id/remarks 意見を新規登録する
GET /meeting_rooms/:id/remarks/:id/edit 意見の編集画面
PUT /meeting_rooms/:id/remarks/:id 意見を更新する
DELETE /meeting_rooms/:id/remarks/:id 意見を削除する
GET /meal_plans/:id/meals/new 食事メニュー決定画面(朝昼夜を選ぶ)
GET /user ユーザー設定画面
PUT /user ユーザー設定を更新する
GET /family 献立表の共有画面
GET /welcome?invitation_token=....... 招待されたときのURL
GET /about 使い方
GET /terms 利用規約
GET /privacy プライパシーポリシー
3回目提出 |Method|Path|Description| |--|--|--| |GET | / | 未ログイン時トップページ| |GET | /auth/:provider/callback | omniauthでのログイン処理| |DELETE | /logout | ログアウト実行| |DELETE | /retirement | アカウント削除実行| |GET | /meal_plans | 週ごとの献立一覧(ログイン後トップページ)| |GET | /meal_plans/calendar | 月毎の献立一覧| |GET | /meal_plans/:id | 献立詳細画面| |GET | /meal_plans/new | 献立新規登録画面| |POST | /meal_plans | 献立を新規登録する| |GET | /meal_plans/:id/edit | 献立の編集画面| |PUT | /meal_plans/:id | 献立を更新する| |GET | /meeting_rooms/:id | 献立ごとの意見一覧画面(相談部屋トップ画面)| |GET | /meeting_rooms/:id/remarks/new | 意見の新規登録画面| |POST | /meeting_rooms/:id/remarks | 意見を新規登録する| |GET | /meeting_rooms/:id/remarks/:id/edit | 意見の編集画面| |PUT | /meeting_rooms/:id/remarks/:id | 意見を更新する| |DELETE | /meeting_rooms/:id/remarks/:id | 意見を削除する| |GET | /meal_plans/:id/meals/new | 食事メニュー決定画面(朝昼夜を選ぶ)| |GET | /user | ユーザー設定画面| |PUT | /user | ユーザー設定を更新する| |GET | /family | 献立表の共有画面| |GET | /welcome?invitation_token=....... | 招待されたときのURL| |GET | /about | 使い方| |GET | /terms | 利用規約| |GET | /privacy | プライパシーポリシー|
2回目提出 |Method|Path|Description| |--|--|--| |GET | / | 未ログイン時トップページ| |GET | /auth/:provider/callback | omniauthでのログイン処理| |DELETE | /logout | ログアウト実行| |DELETE | /retirement | アカウント削除実行| |GET | /meal_plans | 週ごとの献立一覧(ログイン後トップページ)| |GET | /meal_plans/calendar | 月毎の献立一覧| |GET | /meal_plans/:id | 献立詳細画面| |GET | /meal_plans/new | 献立新規登録画面| |POST | /meal_plans | 献立を新規登録する| |GET | /meal_plans/:id/edit | 献立の編集画面| |PUT | /meal_plans/:id | 献立を更新する| |DELETE | /meal_plans/:id | 献立を削除する| |GET | /meal_plans/:id/meeting_rooms/:id/remarks | 献立ごとの意見一覧画面(相談部屋トップ画面)| |GET | /meal_plans/:id/meeting_rooms/:id/remarks/new | 意見の新規登録画面| |POST | /meal_plans/:id/meeting_rooms/:id/remarks | 意見を新規登録する| |GET | /meal_plans/:id/meeting_rooms/:id/remarks/:id/edit | 意見の編集画面| |PUT | /meal_plans/:id/meeting_rooms/:id/remarks/:id | 意見を更新する| |DELETE | /meal_plans/:id/meeting_rooms/:id/remarks/:id | 意見を削除する| |GET | /meal_plans/:id/meals/new | 食事メニュー決定画面(朝昼夜を選ぶ)| |POST | /meal_plans/:id/meals | 意見(提案)を食事メニューに登録する| |GET | /user | ユーザー設定画面| |PUT | /user | ユーザー設定を更新する| |GET | /family | 献立表の共有画面| |GET | /welcome?invitation_token=....... | 招待されたときのURL| |GET | /about | 使い方| |GET | /terms | 利用規約| |GET | /privacy | プライパシーポリシー| ### 補足 - 献立新規登録画面では、MealPlanのform内で`fields_for`を用いて3食分まとめてMealを登録できるようにしたいと思っています。 - まだ献立を作成していない状態で「相談部屋」リンクをクリックしたら、MealPlanとMeetingRoomが新規作成されてすぐにMeetingRoom画面(remarks一覧)に遷移するようにしようと思います。 - 相談部屋を介せずに献立(MealPlanおよびMeal)を新規作成登録したのち、「相談部屋」リンクをクリックした場合は、MeetingRoomだけ新規作成するようにします。 - 「意見(提案)を食事メニューに登録完了した画面」は不要に思えてきたので、リソースから削除しました。
1回目提出 |Method|Path|Description| |--|--|--| |GET | / | 未ログイン時トップページ| |GET | /auth/:provider/callback | omniauthでのログイン処理| |DELETE | /logout | ログアウト実行| |DELETE | /retirement | アカウント削除実行| |GET | /meals | 週ごとの献立一覧(ログイン後トップページ)| |GET | /meals/calendar | 月毎の献立一覧| |GET | /meals/:id | 献立詳細画面| |GET | /meals/new | 献立新規登録画面| |POST | /meals | 献立を新規登録する| |GET | /meals/:id/edit | 献立の編集画面| |PUT | /meals/:id | 献立を更新する| |DELETE | /meals/:id | 献立を削除する| |GET | /remarks | 献立ごとの意見一覧画面(相談部屋トップ画面)| |GET | /remarks/new | 意見の新規登録画面| |POST | /remarks | 意見を新規登録する| |GET | /remarks/:id/edit | 意見の編集画面| |PUT | /remarks/:id | 意見を更新する| |DELETE | /remarks/:id | 意見を削除する| |GET | /remarks/:id/timing | 食事メニュー決定画面(朝昼夜を選ぶ)| |POST | /remarks/:id/timing | 意見(提案)を食事メニューに登録する| |GET | /remarks/:id/done | 意見(提案)を食事メニューに登録完了した画面| |GET | /user | ユーザー設定画面| |PUT | /user | ユーザー設定を更新する| |GET | /menu | 献立表の共有画面| |GET | /welcome?invitation_token=....... | 招待されたときのURL| |GET | /about | 使い方| |GET | /terms | 利用規約| |GET | /privacy | プライパシーポリシー|
yuuu commented 1 month ago

気になった点をコメントします。

motohiro-mm commented 1 month ago

コメントありがとうございます!

Remarkを食事メニューに登録する際のリソースについて

食事メニュー決定というのは、具体的にどのテーブルを操作するものなのかが気になりました ペーパープロトタイプやDB設計を見る限り、操作対象は remarks ではなく dishes ではないでしょうか?

たしかにそうですね。 Remarkのcontentカラムの内容をDishのnameカラムに入れて、timingを選択してDishを登録したい、というのがそのページでやりたいことです。 そうなると操作しているのはDishになるので、/dishes/newのほうが良いのでしょうか?

月毎の献立一覧の年月について

月毎の献立一覧について、表示中の年月はどのように判断しますか?

月毎の献立一覧は、simple_calendarというgemを使用しようと考えています。 このgemを使用するとクエリパラメータで日時が表示されます。 (クエリパラメータでデータがないときは今日の日付を表示するそうです) このgemを試した際の動作の動画です↓

https://github.com/user-attachments/assets/84980891-aca3-490a-8d3c-38a243c2cdaf

カレンダーに載せたいもののモデルにstart_timeというカラムを持たせると日付と連動させられるのですが、モデル内でstart_timeメソッドを定義しても良いので、そのようにする予定です。

# mealsをカレンダー表示したい場合
class Meal < ApplicationRecord
  def start_time
    meal_date
  end
end

質問への回答として適していなければご指摘ください🙏

献立表の共有画面について

献立表の共有画面について、この画面のフォームのPOST/PUT/PATCH先が存在しないようです. 追加をお願いします

「献立表の共有画面」がわかりづらくすみません。 「献立表(Menu)に招待したい側がinvitation_tokenを含めたURLをコピーするための画面」という意味です。 URLはLINEやメールなどで共有するためにコピーしてもらうので、この画面からどこかのページに飛んだり何かを送信したりすることは想定していません。

yuuu commented 1 month ago

回答ありがとうございます 🙏

そうなると操作しているのはDishになるので、/dishes/newのほうが良いのでしょうか?

そうですね。 /dishes/new で良い気がします。

月毎の献立一覧の年月について

simple_calendarを使って実現する旨承知です。

献立表の共有画面について

こちらについても承知です。Menu周りの設計については少し疑問があるので、それはDB設計側でコメントいたします。

motohiro-mm commented 1 month ago

DB設計にあわせてリソース設計も修正しました! https://github.com/motohiro-mm/GohanSummit/issues/34#issuecomment-2343571153 ご確認をお願いいたします!

yuuu commented 1 month ago

@motohiro-mm 修正ありがとうございます 👍 いくつかコメントします 🙏

motohiro-mm commented 1 month ago

丁寧に確認してくださりありがとうございます! https://github.com/motohiro-mm/GohanSummit/issues/34#issuecomment-2343571153 修正してあります!

相談部屋のパスについて

「献立ごとの意見一覧画面(相談部屋トップ画面)」は「相談部屋詳細画面」という扱いにできないでしょうか?

「相談部屋詳細画面」ということは/meeting_rooms/:idであっていますでしょうか? もうひとつ気になっているのですが、相談部屋での画面が全部/meal_plans/:id/meeting_rooms/:id/~としているのですが冗長な感じがしたので、これを/meeting_rooms/:id/~とするのはダメでしょうか? (一旦この形に修正しています)

Mealの登録について

「献立を更新する」と「意見(提案)を食事メニューに登録する」で行うことは重複していないでしょうか?

たしかに実際やっていることとしては同じですね! 同じリソースを使うようにします!

献立の削除について

「献立を削除する」について実際に削除するユースケースはありそうですか? 削除はせずに、献立を更新し続けるような運用になるような気がしています。 削除すると相談部屋で議論した内容も全て消える、という理解であっていますか?

たしかにMealPlanを削除した時点で紐づくMeetingRoom(とそれに伴うRemarks)も削除されますね… MeetingRoom含めMealPlanを全部削除する場面は思いつかなかったので、「献立を削除する」というリソースは無しにしようと思います。 ただ日付間違いで登録してしまったなどはあるかもしれないので、登録したMealPlanの中のMealを全部空欄に更新する、といった仕様はできるようにしたいと思います。 ご指摘ありがとうございます!

yuuu commented 1 month ago

@motohiro-mm 検討ありがとうございます 👍

「相談部屋詳細画面」ということは/meeting_rooms/:idであっていますでしょうか?

はい、あっています。

これを/meeting_rooms/:id/~とするのはダメでしょうか?

これも問題ありません。相談部屋テーブルを作ったことで、そのIDさえ特定できれば意見との紐づけが行えるので。

その他の修正内容についても問題ありません。 DB設計がここから大きく変わらない限り、リソース設計はこれで確定で良いと思っています 👍

motohiro-mm commented 1 month ago

@yuuu

ご確認いただきありがとうございました!✨

motohiro-mm commented 1 month ago

@yuuu

お世話になっております! リソースを追加したいところが出てきたのでご相談させていただきます。

追加したいリソース

PUT  /meeting_rooms  相談部屋の作成

理由

現在相談部屋(MeetingRoom)の実装に着手しています。

現時点でのリソースでは、/meal_plans(献立表一覧)から直接/meeting_room/:id(各日付の相談部屋)にジャンプするように考えていました。 ですがそもそもMeetingRoomが作成されていないとidも取得できないため、このリソースだけでは献立表一覧→MeetingRoom作成→各日付の相談部屋を表示、という流れが実装できませんでした。

/meeting_roomsでMeetingRoomをcreateして、そこからリダイレクトして/meeting_room/:idに行くようにしたいと考えています。

考えているmeeting_rooms_controller.rb ``` class MeetingRoomsController < ApplicationController def show @meeting_room = current_user.family.meeting_rooms.find(params[:id]) @remarks =@meeting_room.remarks end def create meal_plan = current_user.family.meal_plans.find_or_create_by(id: params[:meal_plan]) { |meal_plan| meal_plan.meal_date = params[:meal_date]} meeting_room = current_user.family.meeting_rooms.find_or_create_by(meal_plan: meal_plan) redirect_to meeting_room_path(meeting_room) end end ```

もっと良い方法がある場合は教えていただきたいです🙏 よろしくお願いいたします。

yuuu commented 1 month ago

@motohiro-mm ご相談ありがとうございます。要は「各日付の相談部屋は初回アクセス時に作成したい」ということですよね? Pathに含まれるパラメータのみで作成が可能であれば、 MeetingRoomsController#show にて current_user.family-meeting_rooms.find_or_create_by を呼ぶというのはどうでしょうか?

単純にその方がシンプル、というのも理由ではありますが、提示いただいた設計方法だと後々「やっぱり相談部屋の新規登録画面を作りたい」と思ったときに、打ち手がなくなる懸念があります。

motohiro-mm commented 1 month ago

@yuuu

単純にその方がシンプル、というのも理由ではありますが、提示いただいた設計方法だと後々「やっぱり相談部屋の新規登録画面を作りたい」と思ったときに、打ち手がなくなる懸念があります。

なるほど、createが使われてしまうと従来通りのmeeting_roomの新規作成画面を作りたい時にcreateが使えなくなるということですね。理解しました。

MeetingRoomsController#show にて current_user.family-meeting_rooms.find_or_create_by を呼ぶというのはどうでしょうか?

相談部屋に行くボタンをapp/views/meal_plans/index.html.erbに以下のように書きました。

<%= button_to '相談部屋 >', meeting_room_path(id: meal_plan.meeting_room) %>

app/views/meal_plans/index.html.erbの画面(/meal_plans)を開こうとするとエラーになります。 idがnilになる場合があるからだと思います。

ActionView::Template::Error (No route matches {:action=>"show", :controller=>"meeting_rooms", :id=>nil}, possible unmatched constraints: [:id]):

id以外のもの(meal_planやmeal_dateなど)をパラメータに渡したりもしましたが、結局meeting_roomのidがないのでmeeting_room_pathはエラーになりました。 idがnilになってもエラーにならない書き方がありますでしょうか。 もしくはルーティングの設定をなにか追加する必要があるのでしょうか。 現在のルーティングの設定は以下です。(meeting_room部分のみ)

  resources :meeting_rooms, only: %i[show] 
yuuu commented 1 month ago

@motohiro-mm むむむ、なるほど、idがnilだとLinkHelperを呼び出した時点でエラーになってしまうのですね 💦 当初提案いただいていた create を呼ぶというのも一つの手ですが、もう一つの手として show のルーティングを /meeting_rooms/2024-09-28 のように日付にするのはどうかなと思いました。これが絶対的な正解ではないので、どちらを選択するかはお任せします 🙏

motohiro-mm commented 1 month ago

@yuuu 教えていただいた/meeting_rooms/2024-09-28のように日付をいれるルーティングが良さそうだったので一度それでやってみました! MeetingRoomはカラムでmeal_dateをもっていないため、meeting_roomを取得するのにmeal_planへ毎回参照しにいったり、パスに渡すパラメータ数が多くなってしまったりしてしまいました。 (私の実装があまり良くなかったのかもしれません)

仕様変更への対応は厳しくなりますが、createを追加する形で実装していこうと思います。 相談に乗ってくださりありがとうございました!🙏