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が起こってしまっているから?

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

Dashboards#indexで前月のリンクをクリックすると当月の一覧にリダイレクトされる不具合を修正。

不具合

Dashboards#index

前月へのリンクをクリックすると、/dashboardへリダイレクトされる。

原因

Started GET "/dashboard/2019-12"

vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Processing by DashboardsController#index as HTML
  Parameters: {"year_month"=>"2019-12"}

Redirected to http://localhost:3000/dashboard
Completed 302 Found in 29499ms (ActiveRecord: 0.4ms)

GET /dashboard/2019-12した後に、/dashboardにリダイレクトされている。

Dashboardコントローラを確認する。

# Dashboard#index
def index
  @diary = current_user.diaries.build
  if params[:year_month].nil?
    ....
  elsif Date.strptime(params[:year_month], '%Y-%m').month < Date.today.month
    ....
  else
    redirect_to '/dashboard'
  end
end
#

リクエストのパラメータに:year_monthが含まれる場合に、リクエストに含まれる:year_monthパラメータの月にあたる数値と現在の月の数値を比べ、リクエストした年月の数値の方が小さかった場合に、前月のレコードを検索して返す処理を記述していた。

年が変わって、12月のレコードが 12 < 1 でfalseとなってしまい、else節が実行されてしまうようになっていた。(なんでこんなこと書いたのか覚えてない…)

対処

# Dashboards#index
...
elsif params[:year_month]
....

とした。

結果

月ごとのレコードが表示される様になった。

2019年の振り返りと2020年の目標


2019年の目標

会社に復職するのか、転職するのかを決めてその先に進む。

退職して転職すると決めたので、転職すること。

  • いま振り返ると100%転職なんだけどかなり真剣に考えていた。

    • cotreeのカウンセラーの方とこれまでの棚卸と進路の選択肢の検討を行なった。
    • 転職に行き詰った場合の貯金の推移を計算して、それを根拠に転職することにした。
    • この決定にはいまのところ後悔していない。
  • 転職の実現には残念ながら至らなかった。

    • 8月末にリワーク終了後1人で転職活動をするのではなく、就労移行支援を利用しながら転職活動をすることに決めた。いまは就労移行支援に通っている。
    • 新しい職場で自分の既往や弱点を職場の人に適切に伝えられず、再休職になるのが不安だった。(うつ病で復職2年以内の再休職率は約4割。かなり高い。)

    • いま振り返ってみると、慎重だなとは思う。

  • 転職活動のためのアプリ制作 - 進捗は90%(あと少し)

    • 一年を通して中断を挟みながら続けた。作業時間はトータル270時間。
    • 形にはなってきた。嬉しい。
    • いろんな人に、「完成したら見せてね」と言われていて、それが励み。

3ヶ月ごとの振り返り

1月ー3月
  • 今後の進路について考え、人事と面談。
  • リワークプログラムを探し面談する。3箇所面談した。
  • 退職決定。
  • ワイヤーフレームと機能の洗い出し。
4月ー6月
  • 住んでいた寮の引き払い作業、上司と最後の面談。
  • リワーク開始。
    • 久しぶりに家族以外の人と会話をしてかなり体力的にきつかった。が、徐々に慣れていった。
  • 環境構築とJavascriptの基礎
    • 環境構築がかなりしんどかった。メンターに聞きながらでも2週間かかった。
    • アプリをどう作れば良いのか分からず、文法の学習に逸れてしまった。
7月ー9月
  • リワークでADHDについての発表を行う
    • 過集中で準備に50時間もかけてしまった。
    • 納得のいくプレゼン準備をできたのが初めてで、反響をたくさん貰えて達成感があった。
    • 学んだことを発表することは好きだなと思った。
  • アプリ制作を進める。日記投稿機能・一覧表示機能をつくる。
    • 作りたい機能を詳細に決めて、ではそれを作るためには何が必要なのか?という考え方ができるようになってきた。
10月ー12月
  • 就労移行支援の利用手続きを進める。
  • アプリ制作 体調グラフ機能を作る。また画面を全体的に仕上げた。
  • 10月は過集中してしまった影響で11月に2週間体調を崩す。
    • 自分のこだわりや癖を再認識できた機会でもあった。
  • 就労移行支援の本利用が始まる。
    • 2週間に1度、チームでプレゼンをする講座がためになっている。
    • 限られた時間の中でチームの人と議論しながら資料を作り発表する。仕事の負荷に一番近い。

そのほかチャレンジしたこと、失敗したこと、印象に残っていること

  • ロッキン初参戦
    • BUMPよかった!
  • おせちづくり
  • 卓球
    • リワークで毎日やってた。
  • ランニングサークルを開拓
  • Onのシューズを購入
  • ポケモンソードシールドやった。

  • 鈴木悠平さんの四半期報告会に参加した。

    • そこに参加されていた方とは雰囲気が合いそうだなと思った。参加を続けたい。
  • サッカーの動画をこまめに見るようになった。


2020年の目標

体調を維持し常に余力を確保しておく
  • リワークや就労移行支援に週5で通うと土日はダウンしてしまうことが多かった。
  • 体力的に70-80%の稼働を1年通して続けられるようにしたい。
転職活動
  • 就労移行支援のスタッフと相談しながら、自分にあった働き方・会社を探す
  • 面談を重ね、納得のいく会社に入る
エンジニアコミュニティに参加する
  • 1人で学習・作業することしかしてない。視野を広げたい。
基本情報を取る
サービスを公開する
  • いま作っているアプリをいろんな人が実際に使うものにしたい。休職している人に話してもニーズがあると思われる。
定期的に通える場所を作る
  • ヨガなのか、ランニングなのか分からないけど、そういう場所を作る。
Voicyファンフェスタ
  • 今年も参加したのだけど、体調悪くて見ているだけだった。
  • 来年はパーソナリティの方やリスナーさんと交流してみたい。
ライブ
海外に旅行行く
  • 休職してからまともに旅行行けてない。中国に行きたい。

まとめ

  • 2019年はいろいろとアップダウンはあったけど、一貫して同じ目標を意識して行動することができた。壁を乗り越えられた場面もいくらかあった。よき1年だったと思う。
  • 体調面がかなり回復してきた。
  • 来年も(もう今年だけど)よろしくお願いいたします!

(Chart.js) canvas要素のサイズが変化する不具合を修正した。

アプリ制作

  • 課題1

    • 体調グラフで表示しているカラム(活動量など) をToggleすると、グラフのサイズが

      変化してしまう。

  • 原因

    • カラムをToggleすると毎回Chartを生成していたため。
jQuery('.chart-toggles a').click(function() {
  currentChart.destroy();
  jQuery(this).toggleClass('enabled');
  enableCheck();
  data = {
    labels: chartlabel,
    datasets: [ ACT, MOO, APP ]
  };
  newChart = new Chart(ctx , {
    type: 'line',
    data: data,
    options: options,
  });
  currentChart = newChart;
})
  • 対処
    • Chartを削除・再生成するのではなく、更新するようにコードを修正
jQuery('.chart-toggles a').click(function() {

  jQuery(this).toggleClass('enabled');
  enableCheck();
  data = {
    labels: chartlabel,
    datasets: [ ACT, MOO, APP ]
  };

  currentChart.data = data;
  currentChart.options = options;
  currentChart.update();
})
  • 結果
    • カラムをToggleさせてもグラフのサイズが維持できるようになった。

Bootstrapを使ったサイドバーのサンプル模写など

アプリ制作

  • アプリの修正点を洗い出す。
  • レスポンシブ対応を優先して取り組むことに決定

  • BOOTSTRAP SIDEBAR でサイドバーのサンプルを作成

  • PCとスマホのサイズでスムーズに移行できるナビバーのレイアウトを再考

  • 制作物

Image from Gyazo

  • 次回はアプリに修正を反映する

Procオブジェクトを使い, 指定された期間における各カラムの値の配列を生成する

アプリ制作

実現したいこと

体調グラフ機能

各カラムに1つボタンを作成し, ボタンのON/OFFでカラムの表示/非表示を切り替えられるようにする。

どのように実現するか

指定された期間における各カラムの値の配列を生成し, Viewに渡す。

本日はrails consoleで考えたコードが動作するのかを試した。

# Diaryレコードをグループ化
records = User.diaries.group_by_week(week_start: :mon) { |n| n.diary_date }

# 期間内のDiaryレコードを1つずつ取り出し, カラムの値を配列で返す
get_column_value_proc = Proc.new do |column, records|
   records.map do |record|
    record.send(column)
   end
 end
#=> #<Proc:0x00007ff445dba088@(irb):47>

# Y軸の値のハッシュ(キー: カラム, バリュー: カラムの値の配列)を返す
 columns.each do |column|
    y_axis_value[column] = get_column_value_proc.call(column, records[date_begin])
 end
#=> [:activity, :mood, :appetite]

 y_axis_value
#=> {:activity=>[1, -1, 2, 2, 2, -1, 2], :mood=>[2, -2, -2, 1, 0, 2, 0], :appetite=>[2, 2, -2, 2, 2, 1, 1]}

プロを目指す人のためのRuby入門

Chart.jsにToggle機能を追加しカラムの表示/非表示を切り替える


実現したいこと

体調グラフ機能, ボタンのON/OFFでカラムの表示/非表示を切り替える

メンターから, Ajaxは学習コストが高いのでjQueryでやった方が早くできるとアドバイスを頂いた。

各カラムのボタンのtoggleによって, 対応するdatasetを追加したり、削除したりできるようにしたい。

どう実装するのか?

この記事についているデモの通りに実装していく。

How to add a dataset toggle to Chart.js?

大まかな流れは、

  • ToggleするリンクをHTML作成し, class名をカラム名 + enabledとする
  • JavascriptenableCheck関数を作成
    • 各カラムのクラス名にenabledが付いているかを判定
    • trueなら変数にグラフのdatasetを代入, falseならnilを代入
  • jQuery.readyenableCheckを実行
  • リンクをクリック時にグラフを削除し, enableCheckを再度実行した上でグラフ描画を行う

結果

Image from Gyazo

datasetとlabelなどの値は一旦固定にして, Toiggle機能のみ実装した。

次回はRailsで全カラムのデータをブラウザにレスポンスできるようにする。

その他の作業

jQuery 要素を表示/非表示にする(toggle) を参考にボタンのtoggleを試しに作成する

プロを目指す人のためのRuby入門