createアクションでフォームから間違った値をPOSTした際にエラーのフラッシュメッセージが表示されない

アプリ制作

  • 修正点1

    960px以下で/loginのページにログイン後に表示すべきサイドバーが表示されている。

  • 原因

    ヘッダー要素をログイン前後関係なく表示するようにコーディングしてしまっている。

  • 対処

    logged_inメソッドを使って条件分岐をする。

  • 結果

    ログイン前にサイドバーが表示されなくなった。

  • 修正点2

    User#newの表示が崩れている。

  • 原因

    yieldでリクエストされたテンプレートを表示する際、

    new.html.erbが埋め込まれる親要素がflex directionがrow-reverseになっているため。

  • 対処

    session#newでは表示が崩れていないので、

    Session#newと同じHTMLを記述する。

  • 結果

    User#newで表示が崩れなくなった。

  • 修正点3

    Diary#newのページでエラーのが表示されない。

  • 実現したいこと

    Diary#newのviewページで, 投稿に失敗した際にエラーのフラッシュメッセージを表示させたい。

    Diaryモデルでは投稿の日付(:diary_date)が重複しないようにvalidationを設定しています。

    すでに投稿済みの日付(2020-01-13)で再度投稿した際に、フラッシュメッセージでエラー表示を行いたいです。

  • 状況

    投稿済みの日付をフォームに入力し、POSTしました。すると以下のエラーが発生し、投稿画面には入力した値がフォーム上にそのまま表示され、フラッシュメッセージは表示されません。

app/controllers/diaries_controller.rb:11:in `create'
Started POST "/diaries" for ::1 at 2020-01-14 14:27:03 +0900
Processing by DiariesController#create as JS
  
Parameters: {"utf8"=>"✓", "authenticity_token"=>"hELYtfdo11Si85PhI5MT1VPju020UUYM2ua5IyhfADjW3+EJldcXbwbLdggouVT0Cj2CM739EW+vcyH1pDQ/bA==", "diary"=>{"diary_date"=>"2020-01-13", "activity"=>"-2", "mood"=>"-1", "appetite"=>"0", "content"=>"adas"}, "commit"=>"日記を投稿"}

User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
↳ app/helpers/sessions_helper.rb:3
 (0.2ms)  BEGIN
↳ app/controllers/diaries_controller.rb:11
Diary Create (1.2ms)  INSERT INTO `diaries` (`content`, `activity`, `mood`, `appetite`, `user_id`, `created_at`, `updated_at`, `diary_date`) VALUES ('adas', -2, -1, 0, 1, '2020-01-14 05:27:03', '2020-01-14 05:27:03', '2020-01-13')
↳ app/controllers/diaries_controller.rb:11
 (0.4ms)  ROLLBACK
↳ app/controllers/diaries_controller.rb:11
Completed 500 Internal Server Error in 54ms (ActiveRecord: 17.6ms)


ActiveRecord::RecordNotUnique (Mysql2::Error: Duplicate entry '2020-01-13-1' for key 'unique_diary_per_date': INSERT INTO `diaries` (`content`, `activity`, `mood`, `appetite`, `user_id`, `created_at`, `updated_at`, `diary_date`) VALUES ('adas', -2, -1, 0, 1, '2020-01-14 05:27:03', '2020-01-14 05:27:03', '2020-01-13')):

app/controllers/diaries_controller.rb:11:in `create'
  • 試したこと

    Diariesコントローラのcreateメソッドを以下の様に変更した上で同じことを試しました。(ActiveRecord::RecordNotUniqueをトリガーとして、flashメッセージを表示させようとしました。)

def create
  begin
    @diary = current_user.diaries.build(diary_params)
    if @diary.save
      flash[:success] = '日記が正常に投稿されました'
      redirect_to "/dashboard/#{@diary.diary_date.strftime("%Y-%m")}"
    end
  rescue ActiveRecord::RecordNotUnique
    flash[:danger] = 'メッセージの投稿に失敗しました。'
    render 'new'
  end
end
  • 結果

    flashメッセージは依然として表示されませんでした。Chromeデベロッパーツールでflashメッセージの部分のHTMLが表示されていません。ただ、HTTPステータスは500から200に変化しました。

Started POST "/diaries" for ::1 at 2020-01-14 15:49:07 +0900
Processing by DiariesController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"6vPi65Np1MxzX5Y/jvIHpnoededwTCbWaH2wB2Zfye+4bttX8dYU99dnc9aF2ECHI8BMmXngcbUd6CjR6jT2uw==", "diary"=>{"diary_date"=>"2020-01-13", "activity"=>"-2", "mood"=>"-1", "appetite"=>"-1", "content"=>"asdas"}, "commit"=>"日記を投稿"}
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  ↳ app/helpers/sessions_helper.rb:3
   (0.2ms)  BEGIN
  ↳ app/controllers/diaries_controller.rb:12
  Diary Create (0.8ms)  INSERT INTO `diaries` (`content`, `activity`, `mood`, `appetite`, `user_id`, `created_at`, `updated_at`, `diary_date`) VALUES ('asdas', -2, -1, -1, 1, '2020-01-14 06:49:07', '2020-01-14 06:49:07', '2020-01-13')
  ↳ app/controllers/diaries_controller.rb:12
   (0.7ms)  ROLLBACK
  ↳ app/controllers/diaries_controller.rb:12
  Rendering diaries/new.html.erb within layouts/application
  Rendered layouts/_form.html.erb (2.6ms)
  Rendered diaries/new.html.erb within layouts/application (6.1ms)
  Rendered layouts/_header.html.erb (0.5ms)
  Rendered layouts/_flash_messages.html.erb (0.3ms)
  Rendered layouts/_content_nav.html.erb (0.5ms)
Completed 200 OK in 161ms (Views: 154.5ms | ActiveRecord: 2.0ms)
  • 調べたこと

    flash変数にエラーメッセージが格納されているかをデバッガで確認しました。

    コントローラで指定したメッセージは格納されていました。

From: /Users/bupolang/projects/cocologue/app/views/layouts/_flash_messages.html.erb @ line 3 ActionView::CompiledTemplates#_app_views_layouts__flash_messages_html_erb___4002453590638780199_70244160115980:

    1: <% flash.each do |message_type, message| %>
    2:   <% binding.pry %>
 => 3:   <div class="alert alert-<%= message_type %>"><%= message %></div>
    4: <% end %>

[1] pry(#<#<Class:0x00007fc6192fa350>>)> message
=> "メッセージの投稿に失敗しました。"
[2] pry(#<#<Class:0x00007fc6192fa350>>)> message_type
=> "danger"
[3] pry(#<#<Class:0x00007fc6192fa350>>)> exit
  Rendered layouts/_flash_messages.html.erb (19625.1ms)
  Rendered layouts/_content_nav.html.erb (0.5ms)
Completed 200 OK in 19844ms (Views: 19836.9ms | ActiveRecord: 2.1ms)
  • 原因(仮説)

    データベースでrollbackが起こってしまっているから?

    バリデーションができていない。