Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Railsで時間管理アプリを作成しようと考えています

解決したいこと

現在ポートフォリオを作成するにあたり、DB設計をしています。
サイトの概要としてはユーザーが独自の目標を設定して、その目標に対してどれだけ時間を使ったかを測るため"打刻する"ことで日別と月別で時間を見れると言うものです。

この構造を考えたときに、DBをどのように設計して良いかがわからなくなってしましました。

サイトの流れの構想

1.まずユーザー登録します。

2.目標を設定します(1人のユーザーは何個か設定できます。また、編集も可能)

3.その設定した目標をタイトル名にさせた打刻画面を表示して、開始ボタン・終了ボタンをつけます。
(この時点では開始を押していないので、終了ボタンは発火しないようにします)

4.開始ボタンを押すと開始時間を記録。且、開始ボタンが発火できないようにします。

5.一覧画面に開始時間表示(日付一覧のような表を作成予定)

6.終了ボタンを押すと終了時間を記録。開始と終了の時間の差を合計時間として記録
(この時、total_timeのようなカラムを作成するべきか悩んでます。。。)

7.打刻履歴詳細画面のようなものを作成して、そこでは打刻を修正できるような機能も取り入れたいです。

8.3~6を繰り返しつつ1ヶ月の月の合計時間も一覧に表示。

9.ログアウト

ざっくりですがこのような流れです。

条件

  • ユーザーは1日1回しか打刻記録は残せません※レコードの件数を制限するような事は可能なのでしょうか、、(本当は2回にしたいです。でも、そうするとテーブル数を増やしたり、設計が複雑になりそうだと感じたので1回にしてます。)
  • 00:00を回ったら自動的に次の日として記録されます。(モデルにafter_save~ のように条件を設定して記述するのかな?と考えています。正直まだちゃんと理解していないです。)

思いつくのはこれぐらいです。

作ろうと思い立ったものの、正直わからないことが多すぎて少し完成できるか不安になっています。

技術面は自力で調査して解決しようと考えていますがそちらも質問内容に含みます。すみません。
ただ、DB設計に関してはちゃんと設計しておきたいと思っています。

一応情報を整理してER図も独自で考えてみました。

Untitled Diagram.jpg

分かりづらくなってしまったので質問内容をまとめます。すみません。

  • ポートフォリオ作成にあたり、DB設計がわからなくなってしましました。
  • レコードを制限するといったようなバリデーションみたにな事はできるのでしょうか。
  • 1日を00:00-23:59区切りにして日付を跨いだ場合次の日のレコードとして追加するような設定はできるのでしょうか。
  • 1日2回打刻可能となった場合、テーブルやカラムをさらに細分化することになると考えているのですが合っていますでしょうか、、またその場合、どのように設計するのがベストでしょうか。

まだまだ勉強不足で不明点が多く申し訳ないのですが一度ご覧いただいて、どなたかご教授頂けたら幸いです。

よろしくお願い致します。

1

1Answer

レコードを制限するといったようなバリデーション

  1. work_historyに年月日のカラムを追加する(または年月カラムを変更する。月ごとの集計はfrom-toで取れば良いので)
  2. user_id, target_id, 年月日で一意制約をかける
    1. rails側:validates :user_id, uniqueness: { scope: [:target_id, :年月日] }
    2. DB側(マイグレーション):add_index :work_histories, [:user_id, :target_id, :年月日], unique: true

日付を跨いだ場合次の日のレコードとして追加するような設定はできるのでしょうか。

例えば、以下のような実装が考えられます

  1. 開始時点でwork_historyに終了時刻が23:59のレコードを入れる
  2. その日のうちに終了した場合(user_id, target_id, 年月日で検索してレコードが存在する場合)、終了時刻を更新
  3. 日付をまたいだ場合(user_id, target_id, 年月日で検索してレコードが存在しない場合)新規で開始時刻0:00で終了時刻の入ったレコードを作成

after_saveでやる場合は以下のようになると思います。

  1. 開始時点でwork_historyに終了時刻nilのレコードを入れる
  2. その日のうちに終了した場合(user_id, target_id, 年月日で検索してレコードが存在する場合)、終了時刻を更新
  3. 日付をまたいだ場合(user_id, target_id, 年月日で検索してレコードが存在しない場合)新規で開始時刻0:00で終了時刻の入ったレコードを作成
    1. after_saveで同一user_id, target_idかつ終了時刻nilの前日以前のレコードを23:59で更新

1日2回打刻可能となった場合

上記の実装になればバリデーションを変更+work_historyに終了打刻がされたかのカラムを追加すればできると思います

  1. 一意制約をなくし、当日3件目のレコードが入らないようにバリデーションを作る
  2. 当日に終了打刻していないレコードがあれば新規追加できないバリデーションを作る
  3. 終了打刻時に終了打刻済みのカラムをtrueにする

最後の質問はちゃんと考えられてないので考慮漏れがあるかもしれません。

0Like

Comments

  1. ご丁寧にご回答していただきありがとうございます。大変参考になりました!試してみます。本当にありがとうございます。。

Your answer might help someone💌