🎉

最終課題を終えました

2024/07/19に公開

ドイツに4年ほど住んでいたことがあり、上の写真はその時に自分の部屋にあったヒーター(Heizung)です。
建物全体に温水が入ったパイプが通っており、そこからお湯を引いてくることで部屋を温めるいわゆるセントラルヒーティングで、ドイツではよくある暖房設備です。基本付けっぱなしにしておくそうで、冬の間はオフにするなよ!と、大家さんにめちゃくちゃ念を押されたことを覚えています。(オフにするとパイプが凍結してお湯が出なくなって故障するから、、みたいな説明を受けた気がする)
プログラミングとは全然関係ないですが、テスト画像の一つとして酷使していました。

最終課題を終えました

4月からテックキャンプというプログラミングスクールで学習していて、3ヶ月半ほど(4/8-7/19)で最終課題を無事に終了することができました。
自己紹介で書いた通り現職は塾講師で、もうすぐ夏期講習が始まります。講習中は忙しくなり、これまで通り学習ができないことがわかっていたので、学習を始めた当初から夏期講習が始まるまでに最終課題を終えたいと思っていました。
自分で立てたスケジュールでは夏期講習の1週間前を目処に終わらせる予定でしたが、実装の最終局面で想定より時間がかかり、講習が始まる2日前(ギリギリ❗)に終えることになりました。
今回はこれまでの振り返りをしてみたいと思います。

最終課題の振り返り

commitの粒度

最終課題は機能ごとにコードレビューを依頼してLGTMをもらったらmasterブランチにmergeして、次の機能の実装に移るという流れで進めていきました。
実装の中盤あたりからcommitの粒度[1]が揃っていないことが気になりだしましたが、実装途中の段階では新しい技術の習得で手一杯で全体像を掴めておらず、今回はあまり意識できていませんでした。
これは次回への課題ですね。

ちなみに、このコードレビューがめちゃくちゃ速くてびっくりしました。
全体を通じてたくさんコードレビューを依頼しましたが、どれも対応時間内だと10分程度で返ってきて、そのお陰で休日にとても作業が捗りました。改めてメンターの方々に感謝です。

エラーとの戦い

プログラミングをしているとエラーは付きもので、学習をはじめてから最終課題を終える今までに数々のエラーに見舞われました。

テックキャンプにはプログラミングについてわからないことがあったときに「アクションプラン相談」ができるメンター制度があります。ただ単に答えを教えてもらうのではなく、エラー解決のために検証すべきこと、次に取るべき1手をアドバイスしてもらえる制度です。質問するときには論点を整理(質問フォーマットがあります)してから質問することになっており、現場で働くことになった時に質問をするときの練習にもなっているのですね。

これまでのところ、エラーはメンターに質問することなく全て自己解決することができました。(結果的にですが)
仮説検証からエラーの原因を探っていく作業は大変で時間がかかりましたが、解決するまでの過程でコードの理解が深まり成長を実感できてとても楽しかったです。
カリキュラムにあるアプリとはいえ、独力で1つのアプリをコードレビューを受けながら作り上げた体験から今は達成感&充実感でいっぱいです❗

誤解のないように追記すると、メンターに頼らず独力で進めるべきだ、と考えてこれまで質問をしなかったわけではありません。
実際の仕事では納期があったり、確認しないとわからない問題(仕様など?)などたくさん出てくると思います。そのことを考えて、適切に質問する技術も重要だと考えています。
今回はカリキュラムの進捗に余裕があったため、「タスクを速く終わらせること&質問の練習 VS コードを深く理解すること」を天秤にかけ、後者を選択したということです。せっかくスクールで体系的に学習をしているので、自分で納得しながら進めたいという思いもありました。

エラー集

解決するのに3日以上かかったエラーがいくつかありましたが、今回は印象に残ったエラーを1つ書いてみたいと思います。

バリデーションを通過するがモデルの制約で弾かれる

実装の途中でバリデーションは通過しているのにデータがテーブルに保存されていない、という状況に遭遇しました。
以下のような状況で、コントローラー、マイグレーションファイル、モデルについて書いています。

tests_controller.rb
class TestsController < ApplicationController
  def create
    @test = Test.new(test_params)
    if @test.valid?
      @test.save
      redirect_to root_path
    else
      render :index, status: :unprocessable_entity
    end
  end

  private

  def test_params
    params.require(:test).permit(:A, :C, :D,)
  end

end

マイグレーションファイルでは、各カラムにNOTNULL制約。

20240711021633_create_test.rb
class Test < ActiveRecord::Migration[7.0]
  def change
    create_table :addresses do |t|
      t.string      :A, null: false
      t.integer     :B, null: false
      t.string      :C, null: false
      t.string      :D, null: false
      t.timestamps
    end
  end
end

モデルにはpresence: trueのバリデーション。

test.rb
class Test < ApplicationRecord
  validates :A,         presence: true

  validates :C,         presence: true
  validates :D,         presence: true
  end
end

結論としては、「バリデーションとストロングパラメーターの定義にBが抜けていたのでBなしでもバリデーションを通過したが、モデルのNOTNULL制約で引っかかった」ということでした。
A、C、Dに関してはstring型でまとめてpresence: trueでバリデーションをつけていましたが、Bについてはinteger型でpresence: true以外の別の制約をつける関係で、抜け落ちていたようでした。
さらにコントローラーでストロングパラメーターtest_paramsを定義する際にマイグレーションファイルではなく、モデルのバリデーションを見ながらカラムを書き込んでいたため、ここでも同じBが抜けてしまって見事に?バリデーションを通過してしまっていたのでした。
バリデーションに引っかかった時はエラー文を出すようにしていましたが、NOTNULL制約は弾かれたときにエラーが出なかったため、気づくのに時間がかかってしまいました。

その他

  • Gyazo Videoが使えなくなった
    これは前回の記事(Gyazo Videoが使えるようになった)で書いてみました。
    エラーではないですが本当に困ってしまい、メンターに相談しようと考えていたところ、突破口が閃いて解決できました。

  • アプリをRenderでデプロイできない
    コードレビューが必要なく、ローカルからリモートのmasterブランチ(mainブランチ)へ直接プッシュするときに、わざわざブランチを切ってプッシュ→プルリクエストをしたたため、リモートのmaserブランチにmergeされておらず、その結果デプロイできませんでした。mergeしてmasterブランチに反映させて、無事に解決しました。
    これはGithubの仕組みの勉強不足でした。

今後の予定について

最終課題の追加実装

1つのモデルに対して複数のアソシエーションを設定する仕組みに興味があり、関連する追加実装をしてみようと思います。

オリジナルアプリの企画

卒業までにオリジナルアプリを作ってみようと思います。そのために企画作成から始めます。
これまでに身に着けたスキルを基に、現状感じている課題を解決するためにこのようなアプリを作りたい、というようなものです。

最後に

日本の夏は湿気があり、大変ですね🥵
冒頭に書いた通りドイツに住んでいましたが、ヨーロッパの夏は気温は高くても湿度が高くないので暑くても快適でした。40度を超える日でも水分を取りながら外で1時間ほどランニングをしていましたが、日本の30℃超えの日に走ると日射病で倒れそうです。
逆に室内は冷房が効きすぎて冷えることがあるので、さっと着脱可能な羽織物を用意しておくといいですね。(塾の生徒たちや保護者にも伝えています)
夏期講習&プログラミング、頑張ります❗

脚注
  1. この記事を読んでから特に意識するようになりました【Git】commitの粒度 ↩︎

Discussion