24歳で休職→未経験でエンジニアに転職するまでの3年間

はじめに

24歳のときに適応障害で休職してから, SEに転職するまでの3年間を振り返りました。長い記事です。笑 主にプログラミング学習と体調のことについて、淡々と時系列で残しました。20代で休職中の方やプログラミング 初学者の方の参考になるといいなーと思ってます。身の回りに休職中の人で進路に悩んでいる人がいたら、シェアしてもらえると嬉しいです。

2017年 休職する

4月

  • 新卒2年目に入る.

9月

  • 適応障害と診断されて休職. 実家にもどる.
  • 担当業務がかなり増え、残業が続いたことが原因だった.
  • それに加え, タスクを同時並行的にこなしていくことに苦手感があった.

10月

  • 精神科に通いはじめる
  • 先生から「自分の苦手だったという直感を信じてみると良いかもね」とアドバイスされた
  • 傷病手当金の受給開始 (~2019.3月まで)

2018年 試行錯誤の1年

1月

  • AIエンジニアに転職することを考えはじめた. 大学時代の友人Kくんに相談. 
  • とりあえず数学IAの復習を始める. AIの勉強会に参加.

2月〜3月

4月

5月〜6月

  • 上掲の本に取り組む. エラーが出てはBくんやMくんにアドバイスをもらい, なんとか1周できた. (感想ブログ)
  • 巻末に紹介されていたPyQという学習サービスに取り組む.

7月

  • 体調を崩す
  • 勉強のためにMacBookProを購入(40万円. オーバースペックで後に後悔. 購入は慎重に...!)

8月

9月

  • 転職エージェントと面談する.
  • 某プログラミングスクールのエンジニア転職コースを受験するも不採用. (転職できる可能性は35%とのこと)
  • ポートフォリオを作るためにTechAcademyのWebアプリケーションコースに申し込む

10月

11月

  • 体調を崩す.

12月

  • 何かを変えなければと思い, cotreeのパートナーコースに申し込み, 体調や会社への対応を相談しはじめる.
  • MENTAポートフォリオ作成のメンターと契約.
  • ポートフォリオの画面レイアウトと主な機能を考えた.

年間まとめ

  • 転職を視野に, プログラミングの勉強をつづけた. 430時間ほど.
  • 体調のアップダウンを何度も繰り返した. がんばり過ぎては寝込むというサイクルを続けていた.
  • 次第に自分ひとりではポートフォリオ制作も体調コントロールもむずかしいことに気づき, 外部のサービスを利用し始めた.

2019年 ボトルネックに対処する

1月-2月

  • 人事担当から、面談して今後のことを話したいと連絡を受ける.

  • cotreeのカウンセラーの方に相談しながら, 以下3点の面談準備を進めた.

    • 休職当初の自分が考えていたこと・感じていたことをまとめる
    • 休職にいたった原因・現時点での解決度・復職/復職後に向けての課題をまとめる
    • 今後のプランを複数作成し、それぞれメリットデメリットを検討する
  • 面談では, 休職をつづけながらリワークに通って体調を安定させたいとお伝えした.

  • 会社からの回答を待つ間, リワークの見学に行った.

3月

  • 退職を決意. 人事担当者の方に連絡した.
  • リワーク通所のための手続き.

4月

  • 会社を訪問し退職のご挨拶・寮の引き払い.
  • リワーク利用開始.

5〜8月

  • リワークに週5日通う(午前中はリワーク, 午後はポートフォリオ制作)
  • 休み時間の卓球や, ディスカッションを通して利用者の方と仲良くなった
  • 認知行動療法やカウンセリングを通じて体調のコントロール方法を学んだ

9月

  • 転職活動を進めるために, 就労移行支援事業所を探し始める. (通っていたリワークは, 離職者は3ヶ月までしか通所できないルールのため, 8月末で終了した)
  • ポートフォリオ制作を継続.

10月

11月

12月

  • 体調を保つために, 就労移行のスタッフと週1の面談をはじめる.
  • 就労移行のプログラムを週5日受けながら体調を回復させる.
  • ポートフォリオ制作を継続.

年間まとめ

  • 退職したことでWebエンジニアへの転職がただの方向性から具体的な目標へと変わっていった.
  • リワークや就労移行への通所を通して, 体調をコントロールする方法を学べた.
  • ポートフォリオ制作を少しずつ進めた(300時間程度)
  • 退職に伴い傷病手当金が終了. それ以降, 貯金を取り崩しながらの生活で、金銭的な不安は大きかった.

2020年 ひたすら転職活動

1月〜 3月

  • 失業者給付の受給開始(障害者のため, 最長300日間もらえる)
  • A社面接 (受託システム会社, プログラマ職, 一般オープン) 2次面接にて不採用(残業時間が折り合わず)

4月〜5月

  • 緊急事態宣言に伴い, 在宅で転職活動や就労移行支援のプログラムを行うことになった.
  • B社面接(Webサービス企業, 開発事務職, 障害者枠) 2回目の面接で不採用.
  • C社面接(SES企業, プログラマ職, 障害者枠) 1次面接後, SPIの結果で不採用.
  • 5月初頭から体調を崩す. 在宅になって作業できる時間が増え, 頑張り過ぎてしまった.

6月

  • 在宅を終了し, 就労移行の事務所に再び通い始める
  • D社面接 (受託開発企業, プログラマ職, 一般オープン) 書類選考にて不採用.

7月

8月

  • F社にて企業実習(Javaプログラミング演習)

    • 1日8時間勤務を1ヶ月間続けたことで, 体力に自信がついた.

9月

  • 実習先のF社面接(SES企業, プログラマ職, 一般クローズ)1次面接にて不採用
  • 転職エージェントの利用開始.

10月

  • エージェント経由での応募を続ける

  • 体調を若干崩す(6月からフル回転で頑張り過ぎてしまった)

    • コロナで未経験のプログラマ求人が減っていて, かなり不安を感じていた。

11月

  • G社面接(自社開発企業, プログラマ職, 障害者枠)1次面接通過
  • H社→合格

12月

  • 勤務開始

年間まとめ

  • コロナの影響をもろに受け, 厳しい転職活動だった.(1クリックでの応募を含めると, 60~70社くらい応募, 10社面接, 1社内定)

  • 就労移行のスタッフと毎週面談を重ねて, 地道に試行錯誤してやっと内定をもらえた.

  • 失業給付が無ければ, 途中で諦めていたかもしれない.

    • 前職の退職前にプランを立てた時には失業給付が300日貰えるなんて知らなかった. ラッキーだった.
  • 転職できたのは環境要因がかなり大きいと思う(家族のサポート, 傷病手当金や失業給付, 精神科の主治医との相性, プログラミングに詳しい友人が近くにいたetc..)

    • もちろん自分でも頑張ったけど.
    • ここら辺は, 後日また振り返ってみたい.

MySQLを起動できないエラーを解決した。

MySQLが起動しない

~ $ mysql -u root
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (38)

参照した記事

mysqlが起動できなくなって試行錯誤の末に再インストールした話

MySQLをインストールし直す

sudo rm /usr/local/mysql
sudo rm -rf /usr/local/mysql*
sudo rm -rf /Library/StartupItems/MySQLCOM
rm -rf ~/Library/PreferencePanes/My*
sudo rm -rf /Library/Receipts/mysql*
sudo rm -rf /Library/Receipts/MySQL*
sudo rm -rf /private/var/db/receipts/*mysql*
brew uninstall mysql

PCを再起動し、mysql -u rootcommand not foundになることを確認。

改めて、MySQLをインストール

brew install mysql

すると、インストールは完了したが、エラーが表示される。post-install stepが完了しなかったとのこと。

2020-03-22T07:26:40.099179Z 0 [System] [MY-013169] [Server] /usr/local/Cellar/mysql/8.0.19/bin/mysqld (mysqld 8.0.19) initializing of server in progress as process 2421
2020-03-22T07:26:40.100912Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /usr/local/var/mysql/ is case insensitive
2020-03-22T07:26:41.006686Z 0 [ERROR] [MY-010361] [Server] Fatal error: Illegal or unknown default time zone 'Asia/Tokyo'
2020-03-22T07:26:41.006870Z 0 [ERROR] [MY-013236] [Server] The designated data directory /usr/local/var/mysql/ is unusable. You can remove all files that the server added to it.
2020-03-22T07:26:41.007153Z 0 [ERROR] [MY-010119] [Server] Aborting
2020-03-22T07:26:41.691456Z 0 [System] [MY-010910] [Server] /usr/local/Cellar/mysql/8.0.19/bin/mysqld: Shutdown complete (mysqld 8.0.19)  Homebrew.
Warning: The post-install step did not complete successfully
You can try again using `brew postinstall mysql`

[ERROR] [MY-010361] [Server] Fatal error: Illegal or unknown default time zone 'Asia/Tokyo'と出ている。Timezoneの設定をmy.cnfから削除する必要がある。

mysql --verbose --help | grep my.cnf
#/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf

それぞれのmy.cnfを確認しタイムゾーンの設定を見つけ、削除する。

brew postinstall mysql実行すると、エラーが出ずに完了。

~ $ brew postinstall mysql
==> Postinstalling mysql
==> /usr/local/Cellar/mysql/8.0.19/bin/mysqld --initialize-insecure --user=bupol

これでMySQLを実行できるか?と思ったが、まだできない

~ $ mysql -u root
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (38)

~ $ mysql.server start
Starting MySQL
.. ERROR! The server quit without updating PID file (/usr/local/var/mysql/fuwaakiras-MacBook-puro.local.pid).

エラーメッセージを確認する

~ $ cat /usr/local/var/mysql/xxxxxx-MacBook-puro.local.err

# 省略...
2020-03-22T07:29:59.932031Z 0 [ERROR] [MY-010273] [Server] Could not create unix socket lock file /var/lib/mysql/mysql.sock.lock.
2020-03-22T07:29:59.932330Z 0 [ERROR] [MY-010268] [Server] Unable to setup unix socket lock file.
2020-03-22T07:29:59.932835Z 0 [ERROR] [MY-010119] [Server] Aborting
# 省略...

Unable to setup unix socket lock file.で検索すると、これは所有権の問題らしい。

所有権を自分のユーザ名に変更

~ $ sudo chown username /var/lib/mysql

やっとMySQLを実行できた!!

~ $ mysql.server start
Starting MySQL
. SUCCESS!

日経255の構成銘柄一覧をRubyでスクレイピングして作成する


前回の記事では日経255の企業のうち取り出していたのは半分のみだった。原因は企業名を含むコンポーネントのクラス名に"commponent-list", commponent-list list-evenの2種類のうち前者のみを取り出していたためだった。

実現したいこと

nikkei255のサイトにアクセスし、CSV(No., コード, 会社名)を出力する。

#htmlを解析し、オブジェクト化
page = Nokogiri::HTML.parse(html, nil, charset)
nodes = page.css("div.component-list") #これでlist-evenも取り出すことができる
puts nodes #nodesはNokogiri::XML::NodeSetクラス

上を実行すると、下が出力される。

<div class="row component-list list-even">
    <div class="col-xs-3 col-sm-1_5">6361</div>
  <div class="col-xs-9 col-sm-2_5"><a      href="http://www.nikkei.com/markets/company/index.aspx?scode=6361">荏原</a></div>
  <div class="hidden-xs col-sm-8">(株)荏原製作所</div>
</div>

ここからNodeSet1つごとに, インデックス、コード、会社名を取り出し、配列にして出力したい。

作成したコード

require 'open-uri' #URLにアクセスする為のライブラリを読み込みます。
require 'nokogiri' #Nokogiriライブラリを読み込みます。
require 'csv'

#切り出すURLを指定します。
url = 'https://indexes.nikkei.co.jp/nkave/index/component?idx=nk225'

charset = nil
html = open(url) do |f|
  charset = f.charset #文字種別を取得します。
  f.read
end

#htmlを解析し、オブジェクト化
page = Nokogiri::HTML.parse(html, nil, charset)
nodes = page.css("div.component-list")

# 配列を初期化, 列名を入力
rows =  []
rows << ['No.', 'コード', '企業名']

# 1行ごとに行番号、企業コード、企業名を追加
nodes.each_with_index do |node, index|
  row = Array.new
  row << index + 1
  row << node.search('div.col-xs-3').text
  row << node.search('div.hidden-xs').text
  rows << row
end

# CSVファイルに保存
File.open("/Users/bupolang/projects/webscrape/nikkei255.csv", "w") do |f|
  #データをループ
  rows.each { |line_array|
    p line_array
    #1行ごとに実行
    line_array.each {|i|
      f.print(i)
      f.print(",")
    }

    #行末に改行コードを入力
    f.print "\n"
  }
end

結果

以下のようにCSV形式でデータを抽出することができた。

No. コード 企業名
1 4151 協和キリン(株)
2 4502 武田薬品工業(株)
3 4503 アステラス製薬(株)
4 4506 大日本住友製薬(株)
5 4507 塩野義製薬(株)
6 4519 中外製薬(株)
7 4523 エーザイ(株)
8 4568 第一三共(株)
9 4578 大塚ホールディングス(株)
10 3105 日清紡ホールディングス(株)
11 6479 ミネベアミツミ(株)
12 6501 (株)日立製作所
13 6503 三菱電機(株)
14 6504 富士電機(株)
15 6506 (株)安川電機
16 6645 オムロン(株)
17 6674 (株)ジーエス・ユアサ コーポレーション
18 6701 日本電気(株)
19 6702 富士通(株)
20 6703 沖電気工業(株)
21 6724 セイコーエプソン(株)
22 6752 パナソニック(株)
23 6758 ソニー(株)
24 6762 TDK(株)
25 6770 アルプスアルパイン(株)
26 6841 横河電機(株)
27 6857 (株)アドバンテスト
28 6902 (株)デンソー
29 6952 カシオ計算機(株)
30 6954 ファナック(株)
31 6971 京セラ(株)
32 6976 太陽誘電(株)
33 7735 (株)SCREENホールディングス
34 7751 キヤノン(株)
35 7752 (株)リコー
36 8035 東京エレクトロン(株)
37 7201 日産自動車(株)
38 7202 いすゞ自動車(株)
39 7203 トヨタ自動車(株)
40 7205 日野自動車(株)
41 7211 三菱自動車工業(株)
42 7261 マツダ(株)
43 7267 本田技研工業(株)
44 7269 スズキ(株)
45 7270 (株)SUBARU
46 7272 ヤマハ発動機(株)
47 4543 テルモ(株)
48 4902 コニカミノルタ(株)
49 7731 (株)ニコン
50 7733 オリンパス(株)
51 7762 シチズン時計(株)
52 9412 (株)スカパーJSATホールディングス
53 9432 日本電信電話(株)
54 9433 KDDI(株)
55 9437 (株)NTTドコモ
56 9613 (株)エヌ・ティ・ティ・データ
57 9984 ソフトバンクグループ(株)
58 7186 (株)コンコルディア・フィナンシャルグループ
59 8303 (株)新生銀行
60 8304 (株)あおぞら銀行
61 8306 (株)三菱UFJフィナンシャル・グループ
62 8308 (株)りそなホールディングス
63 8309 三井住友トラスト・ホールディングス(株)
64 8316 (株)三井住友フィナンシャルグループ
65 8331 (株)千葉銀行
66 8354 (株)ふくおかフィナンシャルグループ
67 8355 (株)静岡銀行
68 8411 (株)みずほフィナンシャルグループ
69 8253 (株)クレディセゾン
70 8601 (株)大和証券グループ本社
71 8604 野村ホールディングス(株)
72 8628 松井証券(株)
73 8630 SOMPOホールディングス(株)
74 8725 MS&ADインシュアランスグループホールディングス(株)
75 8729 ソニーフィナンシャルホールディングス(株)
76 8750 第一生命ホールディングス(株)
77 8766 東京海上ホールディングス(株)
78 8795 (株)T&Dホールディングス
79 1332 日本水産(株)
80 1333 マルハニチロ(株)
81 2002 (株)日清製粉グループ本社
82 2269 明治ホールディングス(株)
83 2282 日本ハム(株)
84 2501 サッポロホールディングス(株)
85 2502 アサヒグループホールディングス(株)
86 2503 キリンホールディングス(株)
87 2531 宝ホールディングス(株)
88 2801 キッコーマン(株)
89 2802 味の素(株)
90 2871 (株)ニチレイ
91 2914 日本たばこ産業(株)
92 3086 J.フロント リテイリング(株)
93 3099 (株)三越伊勢丹ホールディングス
94 3382 (株)セブン&アイ・ホールディングス
95 8028 (株)ファミリーマート
96 8233 (株)高島屋
97 8252 (株)丸井グループ
98 8267 イオン(株)
99 9983 (株)ファーストリテイリング
100 2413 エムスリー(株)
101 2432 (株)ディー・エヌ・エー
102 4324 (株)電通グループ
103 4689 Zホールディングス(株)
104 4704 トレンドマイクロ(株)
105 4751 (株)サイバーエージェント
106 4755 楽天(株)
107 6098 (株)リクルートホールディングス
108 6178 日本郵政(株)
109 9602 東宝(株)
110 9735 セコム(株)
111 9766 コナミホールディングス(株)
112 1605 国際石油開発帝石(株)
113 3101 東洋紡(株)
114 3103 ユニチカ(株)
115 3401 帝人(株)
116 3402 東レ(株)
117 3861 王子ホールディングス(株)
118 3863 日本製紙(株)
119 3405 (株)クラレ
120 3407 旭化成(株)
121 4004 昭和電工(株)
122 4005 住友化学(株)
123 4021 日産化学(株)
124 4042 東ソー(株)
125 4043 (株)トクヤマ
126 4061 デンカ(株)
127 4063 信越化学工業(株)
128 4183 三井化学(株)
129 4188 (株)三菱ケミカルホールディングス
130 4208 宇部興産(株)
131 4272 日本化薬(株)
132 4452 花王(株)
133 4631 DIC(株)
134 4901 富士フイルムホールディングス(株)
135 4911 (株)資生堂
136 6988 日東電工(株)
137 5019 出光興産(株)
138 5020 JXTGホールディングス(株)
139 5101 横浜ゴム(株)
140 5108 (株)ブリヂストン
141 5201 AGC(株)
142 5202 日本板硝子(株)
143 5214 日本電気硝子(株)
144 5232 住友大阪セメント(株)
145 5233 太平洋セメント(株)
146 5301 東海カーボン(株)
147 5332 TOTO(株)
148 5333 日本碍子(株)
149 5401 日本製鉄(株)
150 5406 (株)神戸製鋼所
151 5411 ジェイ エフ イー ホールディングス(株)
152 5541 大平洋金属(株)
153 3436 (株)SUMCO
154 5703 日本軽金属ホールディングス(株)
155 5706 三井金属鉱業(株)
156 5707 東邦亜鉛(株)
157 5711 三菱マテリアル(株)
158 5713 住友金属鉱山(株)
159 5714 DOWAホールディングス(株)
160 5801 古河電気工業(株)
161 5802 住友電気工業(株)
162 5803 (株)フジクラ
163 5901 東洋製罐グループホールディングス(株)
164 2768 双日(株)
165 8001 伊藤忠商事(株)
166 8002 丸紅(株)
167 8015 豊田通商(株)
168 8031 三井物産(株)
169 8053 住友商事(株)
170 8058 三菱商事(株)
171 1721 コムシスホールディングス(株)
172 1801 大成建設(株)
173 1802 (株)大林組
174 1803 清水建設(株)
175 1808 (株)長谷工コーポレーション
176 1812 鹿島建設(株)
177 1925 大和ハウス工業(株)
178 1928 積水ハウス(株)
179 1963 日揮ホールディングス(株)
180 5631 (株)日本製鋼所
181 6103 オークマ(株)
182 6113 (株)アマダホールディングス
183 6301 (株)小松製作所
184 6302 住友重機械工業(株)
185 6305 日立建機(株)
186 6326 (株)クボタ
187 6361 (株)荏原製作所
188 6367 ダイキン工業(株)
189 6471 日本精工(株)
190 6472 NTN(株)
191 6473 (株)ジェイテクト
192 7004 日立造船(株)
193 7011 三菱重工業(株)
194 7013 (株)IHI
195 7003 (株)三井E&Sホールディングス
196 7012 川崎重工業(株)
197 7832 (株)バンダイナムコホールディングス
198 7911 凸版印刷(株)
199 7912 大日本印刷(株)
200 7951 ヤマハ(株)
201 3289 東急不動産ホールディングス(株)
202 8801 三井不動産(株)
203 8802 三菱地所(株)
204 8804 東京建物(株)
205 8830 住友不動産(株)
206 9001 東武鉄道(株)
207 9005 東急(株)
208 9007 小田急電鉄(株)
209 9008 京王電鉄(株)
210 9009 京成電鉄(株)
211 9020 東日本旅客鉄道(株)
212 9021 西日本旅客鉄道(株)
213 9022 東海旅客鉄道(株)
214 9062 日本通運(株)
215 9064 ヤマトホールディングス(株)
216 9101 日本郵船(株)
217 9104 (株)商船三井
218 9107 川崎汽船(株)
219 9202 ANAホールディングス(株)
220 9301 三菱倉庫(株)
221 9501 東京電力ホールディングス(株)
222 9502 中部電力(株)
223 9503 関西電力(株)
224 9531 東京瓦斯(株)
225 9532 大阪瓦斯(株)

RubyでWebスクレイピングに初挑戦!

暇つぶし

日経255の構成銘柄一覧からインデックス, コード番号, 社名を抽出してCSV形式にする。

参照する表

Image from Gyazo

HTMLタグにtable要素は使われていない。

作成したコード

require 'open-uri' #URLにアクセスする為のライブラリを読み込みます。
require 'nokogiri' #Nokogiriライブラリを読み込みます。
require 'csv'

#切り出すURLを指定します。
url = 'https://indexes.nikkei.co.jp/nkave/index/component?idx=nk225'

charset = nil
html = open(url) do |f|
  charset = f.charset #文字種別を取得します。
  f.read
end

#htmlを解析し、オブジェクト化
page = Nokogiri::HTML.parse(html, nil, charset)

nodes = page.xpath("//div[@class='row component-list']")

array = []

nodes.each do |node|
  array << node.css('div').map(&:text)
end

outputs = []

outputs << ["No.", "コード", "会社名"]

array.each_with_index{|element, index|
  data = []
  data << (index + 1).to_s
  data << element[0]
  data << element[2]
  outputs << data
}

p outputs

File.open("/Users/*****/*****/webscrape/nikkei255.csv", "w") do |f|
  #データをループ
  outputs.each { |line_array|
    p line_array
    #1行ごとに実行
    line_array.each {|i|
      f.print(i)
      f.print(",")
    }

    #行末に改行コードを入力
    f.print "\n"
  }
end

結果

Image from Gyazo

xpathの指定の仕方をミスしていて、データが121個しかなかった。指定をしっかりすれば、

もれなくデータを引っ張ってこれるかも。ただ、エクセルの方が格段に早く済みそう。w

(Chart.js)チャートUIの改善

Statistics#indexのviewを改善する。

  • labelから西暦を削除する。Viewに渡されたchartlabelを整形する。
const labels = chartlabel;

console.log(labels);
//["2020-01-20", "2020-01-21", "2020-01-22", "2020-01-23", "2020-01-24", "2020-01-25", "2020-01-26"]


var result = labels.map(function( value) {
    return value.substr(5);
});

console.log(result);
//["01-20", "01-21", "01-22", "01-23", "01-24", "01-25", "01-26"]

西暦は削除されたが、月が一桁の際に先頭に0が付いてしまい、見にくい。条件分岐で先頭が0の場合は0を削除したい。

ここまで考えたところで、Reportモデル生成時にラベルを整形した方が、DRYになると気づいた。

そこで、Reportを生成するサービスクラス内のchart_dataメソッドを書き換えた。

#app/lib/generate_report/report.rb
def chart_data(user, date_begin, date_range)
  # labels = date_begin..date_end).to_a
  labels = date_range.map { |date| date.strftime("%-m月%-d日") }
  y_axis_data = data_generator(user, date_begin)
  chart_data = { labels: labels, datasets: y_axis_data }
end

<参考>

Building a chart with Chart.js and Ruby on Rails

【JavaScript入門】配列処理をするmap()の使い方とMapオブジェクトの解説!

【Ruby入門】strftimeで日付・時刻を書式指定して文字列に変換する


  • 画面幅が狭くなるごとにグラフの高さが縮んでしまう。

Chart.jsのオプションで高さを動的に設定できるようにしたい。

いままではViewファイルのJavascriptでオプションを設定していた。

サービスクラスのReportクラスから設定できる様に書き換える。

# app/lib/generate_report/report.rb
module GenerateReport
  class Report
    #省略
    
    def chart_options
      options = { responsive: true,
                  scales: {
                    yAxes: [{
                      ticks: {
                        max: 2,
                        min: -2,
                        stepSize: 1.0
                      }
                    }]
                  }
                }
    end
    
    #省略
  end

Uncaught TypeError: $(...).datepickerと表示される不具合などを修正する

修正点1

#application.html.erb

<head>
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
   <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
   <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
   <script src="https://kit.fontawesome.com/65c7366224.js" crossorigin="anonymous"></script>
   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
   <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
   <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
   <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
</head>
<body>
  #省略
  
  #最下段
  <script type="text/javascript">
      $(document).ready(function () {
        $('.datepicker').datepicker({
          dateFormat: "yy-mm-dd"
        });

        $('.overlay').on('click', function () {
          // hide sidebar
          $('#sidebar').removeClass('active');
          // hide Overlay
          $('.overlay').removeClass('active');
        });

        $('#sidebarCollapse').on('click', function () {
          // open sidebar
          $('#sidebar').addClass('active');
          // fade in the Overlay
          $('.overlay').addClass('active');
        });
      });
    </script>
</body>

このように記述した際にブラウザでエラーが発生する。

Uncaught TypeError: $(...).datepicker is not a function
at HTMLDocument.<anonymous> (dashboard:365)
at e (jquery-3.4.1.slim.min.js:2)
at t (jquery-3.4.1.slim.min.js:2)

原因の仮説

datepickerはjQuery-UIの機能の一つである。jQuery-UIがloadされていないのではないか?

対処

Googleの Hosted LibrariesからjQuery-UIのスニペットをコピーし、application.html.erbheadタグ最下段にペーストする。

結果

datepickerが使用可能になった。

考えたこと

CDNの仕組みとは?


修正点2

diaries#newの投稿日フォームに当日の日付をデフォルトで表示する。

(日付選択の手間を省くことができる。)

対処

以下の様に記述した。

$('.datepicker').datepicker({
  dateFormat: "yy-mm-dd",
  defaultDate: new Date()
}).datepicker("setDate", new Date());

結果

フォームに日付が自動で出力される様になった。


修正点3

Dashboards#indexで、投稿カードのコンディション部分の表示が崩れる。

divとulタグにスタイルを当てていたが、うまくいっていない。

Image from Gyazo

対処

tableを導入した。table要素にはmarginを設定できず、paddingを設定することでレイアウトを微調整した。

# layouts/_diaries.html.erb
<table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody>
    <tr>
      <th>疲労</th>
      <td>
        <ul class="list-group list-group-horizontal">
          <% conditions = condition_generator(diary.activity) %>
          <% conditions.each do |key, value| %>
            <%= content_tag(:li, key, class: "#{class_generator(value)}") %>
          <% end %>
        </ul>
      </td>
    </tr>
# 以下省略
/* style.css  */

/* conditions */
.conditions > table > tbody > tr > th {
  padding-right: 10px;
}

.conditions > table > tbody > tr > th, td {
  padding-bottom: 10px;
}

結果

いままで表示が崩れていたiphone6/7/8サイズの画面でも表示が崩れない様になった。

Image from Gyazo

createアクションでエラーのフラッシュメッセージが表示されない(2)

実現したいこと

Diary#newのviewページで, 投稿に失敗した際にエラーのフラッシュメッセージを表示させたい。 Diaryモデルでは投稿の日付(:diary_date)が重複しないようにvalidationを設定している。 すでに投稿済みの日付(2020-01-13)で再度投稿した際に、フラッシュメッセージでエラー表示を行いたいです。

メンターの指摘

flashオブジェクト にはmessage, message_type共に格納されている。 つまり、controler−>viewまでのデータフローは正しく行われている。

ボトルネックとなっていると考えられる部分はview以降の処理になると推測できる。

確認すべき点

  • Class alert alert-〇〇は正しくCSSが適用されているか
  • 基本的に、alertに反応してフラッシュメッセージを発火するのはBootStrapによって定義されているため

考えたこと1

そもそもflashオブジェクトとは何か?

flashはアクション間で一時的なプリミティブ型(String, Hash, Array)を渡す機能を提供する。flashに渡された値は次のアクションに渡され、flashは初期化される。flashは通知やアラート機能を実装する際に大きな力を発揮する。...

対処

  • _flash_messages.html.erbのクラス名が正しいかを確認する。
    • alert-danger は正しい。
  • Bootstrapが正しく読み込まれているか?
    • _flash_message.html.erbにclass名がalert alert-dangerのdivを書いて、正しく表示されるたか試してみる。結果、正しく表示された。

新しい仮説

Trouble getting flash notice to display in page viewに以下の記述があった。

your layout will not update because Turbolinks is preventing it from doing so. As unlikely as this is, you may wish to test disabling turbolinks for the link you're loading.

Turbolinksがレイアウトの更新を妨害しているとの指摘。このTurbolinksの無効化を試すと良いらしい。

Handling form errors with Rails automatically? #85 に以下の記述があった。

Rails 5 introduced form_with which by default treats all forms as AJAX unless you pass the :local option. The solution for Turbolinks should probably be applied to Rails to work with form_with also. See https://github.com/rails/rails/blob/master/guides/source/working_with_javascript_in_rails.md

Rails5のform_withヘルパーには:localオプションを渡さない限りデフォルトでAJAXが有効になっている。

対処2

  • form_withヘルパーにlocal: trueを渡す

結果

エラーのフラッシュメッセージが表示される様になった。

考えたこと2

  • Turbolinksとは何か?
  • AJAXがなぜflashメッセージの表示を妨害しているのか?