Cursorを使いながら、猫でもわかるHotwire入門 Turbo編をやってみた#1

Hotwireの入口としてお勧めしてもらった記事を読んでいく。

https://zenn.dev/shita1112/books/cat-hotwire-turbo

## Hotwireの特長

HotwireはWebSocket必須ではないという話

これまでREST APIばかりやってきたので、WebSocket試してみたいな…と思いつつ、今回はGraphQLを使うことにしたので、素のWebSocketではなくGraphQL Subscriptionになるかも。

Hotwireはfetchに対してJSONではなくHTMLをレスポンスする

モデルやバリデーションをサーバーサイドに寄せられる。

### Turbo - Turbo Drive/Turbo Frames/ Turbo Streams

- Turbo Drive: 画面表示部分を差し替えて非同期処理にし、全体の表示を高速化してくれる

- Turbo Frames: 特定のタグで囲った範囲のみを更新できる

- Turbo Streams: 複数の要素を指定して更新できる

### turbo-rails

RailsからTurboを便利に使うためのgem

### Stimulus

Turboを使っていれば基本的にJavaScriptは書かなくて良くなるが、複雑になるとJavaScriptを書く必要が出てくる。その場合にStimulusを使って、カオスになりがちなJavaScriptコード上にレールを敷くことができる。

### Hotwire

Turbo + Stimulusのこと。

## チュートリアル1 Railsで管理画面を作る
rails newして、設定をいくつか追加する。

...

最初の`bin/dev`で躓いた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/cbaf437a-154f-47c8-b6aa-37c43d20cfb7.png)

application.cssファイルが存在しないことによるエラーなので、ファイルを追加した。

sassc-railsも不足していたとエラーになったのでそちらも対応した。

今度はBootstrapのSCSSファイルが見つからないというエラー。
cursorにやってもらおうとしたら、インストールされていないyarnを使おうとしていたので、npmを使うように指示。（📝使用可能な選択肢を使用して欲しい）
CSSをビルドする際に依存関係エラーが出たので、いくつか追加でパッケージをインストール。（依存関係のあるパッケージは自動でインストールされないのだっけ...👀）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/ae80ef04-f660-4fc7-afe1-87d3a3ed118b.png)

表示できた！

### importmap-railsとjsbundling-rails
> $ rails newのオプションで--css bootstrapを指定したけれども、その場合は自動的にjsbundling-railsを使うことになるよ。

なるほど...！

### ページネーションの実装
Cursorに`kaminariをインストールして`とお願いしたら、以下をスムーズに設定してくれた。
1. Gemfileにkaminariを追加
2. bundle installでkaminariをインストール
3. 設定ファイル（config/initializers/kaminari_config.rb）を生成
4. デフォルトのビューテンプレートを生成
5. 日本語化の設定を追加

インストールと初期設定などは、公式でしっかりドキュメント化してあるので、生成AIにとって得意な作業領域なのかも。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/356c0ce6-9aec-4e2b-bcb6-95ae92276f06.png)
ページネーションを適用してもらった時に、`New cat`ボタンが巻き込まれてしまったので修正を依頼...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/7fa7661b-5169-4070-ad72-e5ce2464eb70.png)

Cursorが作ってくれたコードが絶妙に惜しかったので手入力しようとしたところ...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/1fae0473-e27b-4bf4-93f5-b4b1fe97add3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/7304e81f-483e-4dcd-bbe9-d1c47f0bfc8e.png)
チュートリアルのコードに極めて近いコードが提案されてびっくり👀

実装を確認しようとすると、Ransackのエラーに遭遇したので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/c6cd1708-cdf7-4135-8545-b68720eac337.png)
モデルに`ransackable_attributes`を定義
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/b4ea16b7-de17-4d17-b852-f5bb842bb327.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/72cbae19-0173-4e5c-b740-0ec120175da5.png)
いい感じだ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/a3b516d9-0fc3-4e2e-b686-48b9f1784b0c.png)

ソート機能もスムーズにつけられた

### Bootstrap5で見た目を整える
> 🐱 変更量が多いので、こちらのコミットを参考にしてね。

とのことでしたが、Cursorに`Bootstrap5を使って見た目を整えて`とお願いしたら良い感じになった

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/10dc6382-29e5-4a65-8d91-04e26fb33785.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2559587/0f886058-4ca0-49f7-aa6d-e01501931bf2.png)

ページネーションの部分と、その下のボタンの下に余白がないのがちょっとだけ惜しい！

### インラインバリデーションの実装
- モデルにバリデーションを追加
- bootstrap_formをインストール
- CSSを設定

内容が少し複雑だったので、「モデルにバリデーションを追加」とbootstrap_formフォームからバリデーションを削除する部分は、Cursorへの命令を分割した。

## 感想
### Cursor
Cursorを使うことで、最初の立ち上げがとても速くなったと感じた。一方で、差分を注意深くみていかないと、たまに全く関係ない変更が入っていることがある。

### Hotwire
説明を読んだことで、Hotwireのイメージが掴めた。