質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

88閲覧

rails 6 でバリデーションを作動できない

G23

総合スコア8

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2024/03/26 21:06

実現したいこと

rails6を使ってタスク管理アプリを作成中です。
タスク作成の際にバリデーションで予定期間のエラーを表示したいです。
具体的には開始日と終了日があり、まずどちらかもしくは両方が空欄だとエラーメッセージを出し、開始日より前の日付で終了日を入力するとエラーメッセージを出すようにしたいのです。

発生している問題・分からないこと

開始日終了日両方が空欄の場合、片方空欄の場合どちらもエラーが出ます。
ただ開始日より早い日を終了日に指定した場合はメッセージが出ます。

エラーメッセージ

error

1両方空欄の場合 2NoMethodError in TasksController#create 3undefined method `<=' for nil:NilClass 4Extracted source (around line #7): 5 6 def start_end_check 7 errors.add(:end, "は開始日より前の日付は登録できません。") unless 8 self.start <= self.end 9 end 10 11片方空欄の場合 12ArgumentError in TasksController#create 13comparison of Date with nil failed 14Extracted source (around line #7): 15 16 def start_end_check 17 errors.add(:end, "は開始日より前の日付は登録できません。") unless 18 self.start <= self.end 19 end 20

該当のソースコード

index.html.erb

1<h1>タスク一覧</h1> 2<div><% flash.each do |key, value| %> 3 <%= content_tag(:div, value, class: key) %> 4 <% end %> 5</div> 6<table class="head"> 7 <thead> 8 <tr> 9 <th>iD</th> 10 <th>タイトル</th> 11 <th>開始日</th> 12 <th>終了日</th> 13 <th>終日</th> 14 <th>更新日</th> 15 </tr> 16 </thead> 17 <tbody> 18 <p>今日の日付:<%= l @tasks_today, format: :default %></p> 19 20 <% @tasks.each do |task| %> 21 <tr> 22 <td class="id"><%= task.id %></td> 23 <td class="title"><%= task.title %></td> 24 <td class="start"><%= l task.start, format: :default%></td> 25 <td class="end"><%= l task.end, format: :default %></td> 26 <td class="comp"><% if task.completed == 1 %> 2728 <% else %> 29 <!-- タスクが未完了の場合表示しない --> 30 <% end %></td> 31 <td class="up"><%= l task.updated_on, format: :time %></td> 32 <td><%= link_to '編集', edit_task_path(task),class:"edit" %></td> 33 <td><%= link_to '詳細', task_path(task),class:"show" %></td> 34 <td class="delete"><%= button_to '削除', task_path(task.id), method: :delete, data: {confirm: "削除してもよろしいですか?"} %> 35 </td> 36 </tr> 37 <% end %> 38 </tbody> 39</table> 40<p>合計タスク数:<%= @tasks_count %></p> 41<%= link_to 'タスクの追加', new_task_path, class:"add" %>

task.rb

1class Task < ApplicationRecord 2 validates :title, :description, :start, :end, presence: { message: "を入力して下さい。" } 3 4 validate :start_end_check 5 def start_end_check 6 errors.add(:end, "は開始日より前の日付は登録できません。") unless 7 self.start <= self.end 8 end 9 10 11 validates :title, length: { maximum: 20, message: "は20字までにして下さい。"} 12 validates :description, length: { maximum: 500, message: "は500字までにして下さい。"} 13end

20240321140942_create_tasks.rb

1class CreateTasks < ActiveRecord::Migration[6.1] 2 def change 3 create_table :tasks do |t| 4 t.string :title 5 t.text :description 6 t.date :start 7 t.date :end 8 t.boolean :check 9 t.integer :completed 10 t.datetime :updated_on 11 12 t.timestamps 13 end 14 end 15end

tasks_controller.rb

1class TasksController < ApplicationController 2 def index 3 @tasks = Task.all 4 @tasks_count = Task.count 5 @tasks_today = Date.today 6 end 7 8 def new 9 @task = Task.new 10 end 11 12 def create 13 @task = Task.create(task_params) 14 if @task.save 15 redirect_to controller: :tasks, action: :index 16 flash[:notice] = "タスクを作成しました。" 17 else 18 flash.now[:alret] = "作成に失敗しました" 19 render 'new',status: :unprocessable_entity 20 end 21 end 22 def edit 23 @task = Task.find(params[:id]) 24 end 25 def show 26 @task = Task.find(params[:id]) 27 end 28 def update 29 @task = Task.find(params[:id]) 30 if @task.update(task_params) 31 flash[:notice] = "更新しました。" 32 redirect_to tasks_path 33 else 34 flash.now[:notice] = "更新に失敗しました" 35 render 'edit',status: :unprocessable_entity 36 end 37 end 38 def destroy 39 @task = Task.find(params[:id]) 40 @task.destroy 41 redirect_to tasks_path,notice:"削除しました。" 42 end 43 44 45 private 46 def task_params 47 params.require(:task).permit(:title,:description,:start,:end,:completed,:updated_on) 48 end 49 end

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

似た事例を見つけ、nilメソッドやblancメソッドを使うらしいということは分かりましたが、具体的にどう使えばいいか分からない状態です。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

開始日終了日両方が空欄の場合、片方空欄の場合どちらもエラーが出ます。

エラーメッセージのとおりです。空欄(nil)の場合、日付の大小比較自体が不可能です。

presenceがあっても他のバリデーションは実行されますので、nilの場合は大小比較のバリデーションを無言でスルーさせましょう。

ruby

1 def start_end_check 2 return unless start && self.end # 片方がnilならそのまま抜ける 3 errors.add(:end, "は開始日より前の日付は登録できません。") unless start <= self.end 4 end

投稿2024/03/26 21:53

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

G23

2024/03/27 14:44

回答ありがとうございます。! 無事に解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問