$shibayu36->blog;

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

Rails勉強し直している - Webアプリケーション編

Rails勉強し直している - DB操作編 - $shibayu36->blog;に引き続きRailsを勉強し直している。今回はHatena-TextbookのWebアプリケーションの課題を通して学習した。

作ったもの

diffはこの辺。ユーザーが存在する前提で、記事のCRUD処理を実装した。

今回学んだことを雑多に記録していく。

/:username/entries/:id のようなルーティングを作る方法

あるユーザーの記事一覧というURLを作るため、/:username/entries/:id というルーティングが作りたかった。gitlabのこの辺とかを参考にすると、scopeを使うと良さそうであった。

例えばこんな感じ。

  scope '/users/:username' do
    resources :entries
  end

またルーティングヘルパーにUserモデルを渡すだけで /users/shibayu36/... みたいなURLを作って欲しい。今回はそこまではやらなかったが、モデルにto_paramというメソッドを作ることで、このようなことができそうだ。参考: https://github.com/gitlabhq/gitlabhq/blob/5c2b90563fd488c3e54c3ff1183e4a2bb9c1caba/app/models/project.rb#L1489-L1495

RecordNotFoundの例外が出たときに自動で404を表示する

ApplicationControllerでrescue_fromを書いてハンドリングしてあげることで対応できる。大域脱出を使うのは微妙と思いつつ、GitLabやrubygems.orgでも普通に使われているし、そういうインターフェースであると考えれば良いと感じた。

class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found

  private

  def record_not_found
    render plain: '404 Not Found', status: :not_found
  end
end

Tailwind CSSwatchを別のDockerコンテナで実行

Tailwind CSSを導入し、bin/rails tailwindcss:install を実行すると、Procfileで管理されて bin/dev で複数プロセスを実行するモデルになった(参考)。

このやり方はコンテナ利用の場合だと微妙だなと思ったので、docker-compose.ymlで別のコンテナを立ち上げてwatchするようにしてみた。この時、tty: trueを設定してあげないと起動直後に落ちてしまうことに注意。

https://github.com/shibayu36/rails-playground/commit/a669cbf7cef8964822c6f8324e625a0c4315dd1f

  tailwind:
    build: .
    command: bin/rails tailwindcss:watch
    tty: true
    volumes:
      - .:/app

その上で結局Tailwindを使ってデザインするのがだるくなって、ひとまず今回は撤退した。

参考: tailwindcss exits even with —watch - only on Docker · Issue #44048 · rails/rails · GitHub

he solution was to add tty: true to docker-compose.yml since esbuild terminates when stdin is closed. Maybe tailwindcss behaves similarly.

Dockerコンテナ内で立ち上がったRailsアプリケーションをdebug.gemでデバッグ

https://github.com/ruby/debug#remote-debugging のようにRemote debuggingの設定をしておくと良いらしい。https://inspirnathan.com/posts/147-debug-ruby-on-rails-in-docker/ の記事も参考になる。

自分はdocker-compose.ymlのデフォルト設定でRails起動時に必ずrdbgを通すようにするのは微妙だなと思い、debug.gemを使いたいときに使うoverride用のdocker-composeファイルを用意することにした。

docker-compose.with-debug.yml (https://github.com/shibayu36/rails-playground/commit/5e8ba91d6dd445843c784ea6144368932cbf4b84)

version: '3'
services:
  web:
    command: rdbg -n --open --host 0.0.0.0 --port 12345 -c -- bin/rails s -p 3000 -b '0.0.0.0'
    ports:
      - 12345:12345

このファイルを用意した状態で次のようにdebug.gemを通した状態でRailsのコンテナを起動する。

docker compose -f docker-compose.yml -f docker-compose.with-debug.yml up

起動したら以下のコマンドでアタッチすると良い。

rdbg --attach 12345

参考

まとめ

今回はWebアプリケーションの課題をRailsで解いてみて、Railsの学び直しをしてみた。本当に簡易的ではあるが開発の雰囲気を掴めてよかった。