$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

Docker・MySQL・RuboCop・RSpec・factory_botを導入したRailsプロジェクトを作る

Rails勉強し直している - DB操作編 - $shibayu36->blog; の初期セットアップ部分で言及したとおり、Rails・Docker・MySQL・RuboCop・RSpec・factory_botという構成でやってみた。その構成を初期セットアップする方法についてブログ記事に残しておく。

作ったプロジェクトは https://github.com/shibayu36/rails-project に公開している。

Railsプロジェクトの作成

rails newを使って作成する。databaseをMySQLに指定する。テストは後でセットアップするため--skip-testする。それ以外もひとまず不要そうなものは除外する。

rails new rails_project --skip-test --database=mysql --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-storage --skip-action-cable

RSpecの導入

以下をGemfileに入れ

group :development, :test do
  gem "rspec-rails"
end

bundle installとrspec:installを実行。

bundle install
bin/rails generate rspec:install

Dockerの導入

導入がちょっと複雑なので、e2d7b7bd のcommitを見ると早い。ポイントとしては

  • 環境変数でDBアクセスの設定をできるようにする
  • named volumesを使えば簡単にMySQLのデータを永続化できる
  • pidファイルのハンドリングをしないと2回目以降立ち上がらなくなってしまう
  • MySQLの接続ホストをlocalhostにすると、port指定してもmysql.sockを見てしまうので、127.0.0.1を明示的に指定する

RuboCopの導入

Gemfileに

group :development do
  gem 'rubocop', require: false
  gem 'rubocop-rails', require: false
  gem 'rubocop-rspec', require: false
bundle install

後は.rubocop.ymlに以下のような設定をし、自分でカスタマイズしていく。

require:
  - rubocop-rails
  - rubocop-rspec

AllCops:
  Exclude:
    - "vendor/**/*"
    - "db/**/*"
    - "config/**/*"
    - "bin/*"
    - "node_modules/**/*"
    - "Gemfile"
  NewCops: disable

factory_botの導入

先にmodelを作っておく。

bin/rails generate model User name:string:uniq

Gemfileに追加し、bundle install。

group :development, :test do
  gem "factory_bot_rails"

後はfactory_botのための定義をしていくとよい。851ad8 のcommitを参考。ポイントとしては

  • spec/support/以下を自動で読み込む設定を入れた
  • spec/support/factory_bot.rb でFactoryBot::Syntax::Methodsをincludeすることで、namespace指定なしでcreate(:user)とかできるようにした
  • factory定義ではsequenceを使うことで、同一の名前をつけないように

まとめ

以上でDocker・MySQL・RuboCop・RSpec・factory_botを導入したRailsプロジェクトを作ることができた。今後Railsプロジェクトを作るときの参考にしたい。

子供の熱性けいれんを初体験した

すごく焦ったけど良い形で対応できたので書いておく。

状況

子供が40度近い熱が出たので小児科へ。インフルエンザA型の診断を受けて薬をもらう。自転車での帰り道に違和感を感じたので後ろを振り向いたら、子供がけいれんを起こしていて泡も吹いていた。

熱性けいれんのことも頭によぎりつつ、今まで体験したことなかったので自転車を停めてすぐに119連絡。呼吸を確認してくださいと言われたので確認すると大丈夫だった。けいれんが治っても意識は戻らなかったので救急車の到着を待つ。救急車の中でけいれんの様子を救急隊員に報告する。この時熱は40.6度まで上がっていた。受け入れ病院の電話を聞きながら1~2個から断られているのを聞いて、医療崩壊怖いと感じる。

病院に着いた時、反応は薄いが多少子供の意識が回復していた。けいれんの様子や意識の回復の様子から考えて、単純性の熱性けいれんだろうと病院が判断。けいれんを防ぐ坐薬を入れてもらい、しばらくしてから帰宅した。

経験と知見

素人の知見は怖いので熱性けいれんの詳細は病院のサイトを見てもらいたい。ただ自分の経験をまとめておくと参考になりえると思うので、書いておく。

  • 自転車で違和感を感じたら、すぐに見てあげることが大事
    • 自転車で違和感を感じた時、最初は子供が自転車で寝たときのいつもの重みを感じて、寝ちゃったのかなと感じた。しかし、細かく振動しているなど、いつもと何か違うぞという違和感を感じた。そういう時、直感を信じてすぐに見てあげることが大事
    • このときの直感を養うためには、いつも育児に関わる必要があるので、育児をしましょう
  • インフルエンザのけいれんはとくに怖いので、けいれんの様子を観察して覚えておくことが大事
    • インフルエンザでのけいれんは、重篤な症状の可能性もある。重篤かそうでないかの判断軸としてけいれん時の様子が大事なので、けいれん継続時間やけいれんの左右対称性を観察しておくことが大事なようだ
    • 熱性けいれんの初期対応はちゃんと医療機関のサイトを参考にしましょう。たとえば https://caps-clinic.jp/febrile-seizure/ とか
  • 対応は安全側に倒す
    • 熱性けいれんの知識は多少あったので、「救急車を呼ぶのは様子を見てから」みたいな文章が頭によぎった
    • しかし、これまで起きてなかったのにはじめて起きたこと、外で起きたことなどから、とにかく安全側に命が助かる方向の判断をした方が良いと考え、即座に119番連絡をした
    • その後に調べてみると、そもそも意識がしばらく戻らなかったし、インフルエンザきっかけという理由もあったので救急車呼ぶ案件っぽかった。安全側に倒して良かった
  • マインドフルネス瞑想をやっていたのが、緊急対応に意外と役に立った
    • けいれんを最初に見た時、正直めちゃくちゃ慌てていた。その状態で冷静に判断と対応をしなければならない
    • 自分は1~2日に1度くらい体調を整えるためにマインドフルネス瞑想をしているのだが、そのおかげか「慌てている自分」に早めに気づけて、「どういう精神状態でも呼吸をゆっくりすると穏やかになる」という知識もあった
    • 119番連絡している時もとにかく呼吸をゆっくりすることを意識したら、ある程度落ち着いて連絡できた

まとめ

熱性けいれんをはじめて対応すると本当に慌てますが、冷静にやっていきましょう...インフルエンザも流行していて怖いですね。

昨日はブログの予約投稿をしていたので、タイミング的に救急車に乗りながらブログを更新する人みたいになってて笑ってしまった。

Rails勉強し直している - DB操作編

基本に戻ろうと思い、Railsも勉強し直している。勉強し直しの時、Hatena-Textbookの課題を使うことが多いので、今回もそのようにした。

今回はデータベースの課題Railsを使ってやってみた。

作ったもの

この辺がdiff。かなり探索的に作ったのでcommitはごちゃっとしている。

簡易的にlist / add / deleteができるように作った。

bin/rails runner diary.rb add shibayu36 title body
bin/rails runner diary.rb list shibayu36 title body
bin/rails runner diary.rb delete shibayu36 3

あとは今回学んだことを雑多に書いていく。

Railsの初期セットアップ

何もわからず初期セットアップをしたので右往左往してしまったが、MySQL使いつつ、RSpec使ってみたいにするなら、こんな感じでセットアップした方が良さそうだった。

# databaseを切り替えて、testは入れないでおく
$ rails new project_name --database=mysql --skip-test

# それ以外色々不要なものを外すのであれば、オプションを色々つける
$ rails new project_name --database=mysql --skip-test --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-storage --skip-action-cable

その後rspec-railsを入れて初期セットアップ

group :development, :test do
  gem "rspec-rails"
end
$ bundle install
$ bin/rails generate rspec:install

最終的には、Rails + Docker + MySQL + RuboCop + RSpec + factory_botというような構成にしてみたのだけど、この辺りはまた別の記事で書きたいと思う。

docker composeで起動するときに2回目以降サーバが立ち上がらない問題

A server is already running. Check /app/tmp/pids/server.pid.というエラーになって立ち上がらなくなる。こちらについては、ENTRYPOINTを設定してスクリプトで毎回消す、起動コマンドで削除を入れる、pidファイルの作成先を/dev/nullにするなどいろんな方法で回避できそうだった。

参考

モデルの作成

rails generate modelで結構いい感じにやってくれる。たとえば

bin/rails generate model User name:string:uniq

とすると、id/created_at/updated_atは勝手にできた上でuniqueなnameカラムを作ってくれる。NOT NULLとかを付けたいと思ったなら、migrationファイルにnull: falseとか書いておけば良い。

リファレンスを付けたいときはこんな感じ。

bin/rails generate model Diary user:references name:string

一瞬でできて便利。

参考: Active Record マイグレーション - Railsガイド

utf8mb4_0900_ai_ci

開発していたらMySQLのcollationがutf8mb4_0900_ai_ciというものになっていた。見慣れないなーと思って調べたら、MySQL 8系からcollationのデフォルトがこれになったようだ。

今回はこのままでも全然問題なかったのだけど、変える時はどうするのかなと思い調べた。database.ymlにcollationを設定し、DBを作り直すと良いようだった。

collation: utf8mb4_general_ci
docker compose exec web bin/rails db:drop db:create

参考

app/以下に別ディレクトリを作るときのautoload

今回diary.rbにはできる限り実装を書かずに別のところに実装を書く方針とした。app/models/配下に書いても良いのだけど、試しに別のディレクトリを作るということをやってみたかった。そこでapp/commands/というディレクトリを切ったところ、autoload周りでハマってしまった。

最初はapp/commands/add.rbというのを作り、中にCommands::Addクラスを作っていた。これがRailsのautoloadのルールに則っていなかったため、エラーとなってしまった。

本来のルールは、app/commands/add_command.rbにAddCommandというクラスを作る必要があった。つまり

  • app/以下の1段目はnamespaceとして解釈されない
  • 2段目以降が解釈される。そのため、commands/add_command.rbのように、suffixにそのディレクトリ固有の名称を付けるのが一般的
    • controllerもcontrollers/users/diaries_controller.rb みたいになるのと同様

参考: https://railsguides.jp/autoloading_and_reloading_constants.html#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E6%A7%8B%E9%80%A0

GitHub Copilot便利すぎ

色々理由があって、ちゃんとGitHub Copilotを使ってなかったのだけど、今回は使ってみようという気持ちになった。便利すぎた。

具体的には

  • 実装書くときに、やりたいことに対して使ったら良さそうなメソッドを推薦してくれる感覚があった
  • テストを書き始める前に、ひとまず補完を試すと、テスト全体が補完されるという便利さ
    • テストケースの場合分けはそれっぽい感じになっている感覚だった。それを自分のイメージに合わせて細かく調整していく形
    • テスト自体も色々書いていると、have_attributes使ったらもっと簡単に書けるとかを推薦してくれて楽
  • テストを書いている時に繰り返しで入力する項目とかは、改行入れるたびに勝手に補完された
  • 英語のコメント書いている時に、英語自体が補完される...

という感じで、学習効率が異常に上がる感覚だった。今回はChatGPTを使ったり、GitHub Copilot使ったりと、AIを使った学習の高速化がすごいと実感できた。

まとめ

今回はRailsのDB周りの操作を勉強し直してみた。ちゃんと課題をやってみると自分が何もわかっていないことが実感できて便利。次はこれをWebからアクセスできるようにしてみたい。