開始時刻と終了時刻を保存する
railsで、タスクの開始時刻と終了時刻を保存するプログラムを作ります。
自己流の部分が多いので、あくまでやり方の1つとして参考にしてくださると幸いです。
※今回は、開始、終了時刻を保存することをメインに扱います。削除、編集機能や見た目は勘弁してください。
考え方
開始、終了フォームを1度だけしか押せない仕組みを目指します。
具体的には、タスクの開始時刻のデータが入っている場合は開始ボタンを表示しないように、ビューの中にif文を書きます。
この考えに至った経緯は、以下の通りです。
・タスク(Task)に、開始時刻(StartTime)と終了時刻(StopTime)を紐付ける
→問題点:何回でも開始し、終了できてしまう。
・StartTimeのデータが入っている時(開始している時)、ボタンを表示させないようにする。
・StopTimeも上と同様にする。
準備
ターミナル
rails new _6.0.0_ アプリ名 -d mysql
cd アプリ名
bundle install
モデルの作成
rails g model task
rails g model start_time
rails g model stop_time
モデルの修正
間違いがありましたら、ご指摘お願いします。
class Task < ApplicationRecord
has_one :start_time
has_one :stop_time
end
class StopTime < ApplicationRecord
belongs_to :task
end
class StartTime < ApplicationRecord
belongs_to :task
end
マイグレーションファイル
class CreateTasks < ActiveRecord::Migration[6.0]
def change
create_table :tasks do |t|
t.string :title
t.timestamps
end
end
end
class CreateStartTimes < ActiveRecord::Migration[6.0]
def change
create_table :start_times do |t|
t.references :task, foreign_key: true
t.timestamps
end
end
end
class CreateStopTimes < ActiveRecord::Migration[6.0]
def change
create_table :stop_times do |t|
t.references :task, foreign_key: true
t.timestamps
end
end
end
ターミナル
rails db:create
rails db:migrate
ルーティング
Rails.application.routes.draw do
root "tasks#index"
resources :tasks, only: [:index, :create] do
resources :start_times, only: :create
resources :stop_times, only: :create
end
end
使うものしか指定していません。
また、今回は、ネストしていますが、実はしなくても作れます。
コントローラー
ターミナル
rails g controller tasks
rails g controller start_times
rails g controller stop_times
class StartTimesController < ApplicationController
def create
StartTime.create(start_time_params)
redirect_to root_path
end
private
def start_time_params
params.permit(:task_id)
end
end
class StopTimesController < ApplicationController
def create
StopTime.create(stop_time_params)
redirect_to root_path
end
private
def stop_time_params
params.permit(:task_id)
end
end
class TasksController < ApplicationController
def index
@tasks = Task.all
end
def create
task = Task.create(task_params)
redirect_to root_path
end
private
def task_params
params.permit(:title)
end
end
ビュー
urlは、rails routesで確かめて記入してください。
-# タスク保存フォーム
= form_with url: tasks_path, method: :post do |f|
= f.text_field :title
= f.submit "send"
-# タスク一覧表示
- @tasks.each do |task|
%br
タイトル
= task.title
-# 時間を確認したい場合は記載してください。
- if task.start_time != nil
%br
開始時刻
= task.start_time.created_at
%br
- if task.stop_time != nil
終了時刻
= task.stop_time.created_at
%br
%br
-# ここまで
- if task.start_time == nil
= form_with url: task_start_times_path(task_id: task.id), method: :post do |f|
= f.submit "開始"
%br
- if task.start_time != nil && task.stop_time == nil
= form_with url: task_stop_times_path(task_id: task.id), method: :post do |f|
= f.submit "終了"
%br
今回は、new.html.hamlを全く作っていません。
しかしform_withで、createアクションに対応するurlを指定し、method: :postをつけることで直接保存できるようになります。
うまくいかない場合は、binding.pryなどを使い、送っている値、受け取っている値を確認すると良いと思います。
まとめ
力技で作った感じがするので、もっと良い方法がある場合は、ぜひコメントしてください!