Rails7をちょっと試す（turbo_frame_tag あるいは、さらばJavascript編）

## はじめに

Rails 7.0.0 には、 [Turbo](https://github.com/hotwired/turbo-rails) が組み込まれています。
今回はその中で、 `turbo_frame_tag` を試してみたいと思います。
`turbo_frame_tag` を使って、詳細画面を表示したまま編集できるようにするSPAっぽいことをやってみます。

`turbo_frame_tag` を使うと、Javascript を1行も書くことなく SPA を書けるんじゃないかと妄想しています。

以下のバージョンで確認しました。

- Ruby 3.0.2
- Rails 7.0.0
- npm 8.3.0
- yarn 1.22.17

## Rails プロジェクトを作る

新しくRailsプロジェクトを作ります。このとき `
(データベースオプションを指定しているのに深い意味はありません。)

```shell
mkdir rails_sandbox
cd rails_sandbox
rails new . --database=postgresql
```

## scaffold を実行する

scaffold を使って簡単なCRUDを作ります。

```shell
bin/rails g scaffold User name email
```

## DBを作成し migration を実行する

```
bin/rails db:create db:migrate
```

## 詳細画面で編集できるようにする

詳細画面で `Edit this user` をクリックするとページの遷移なしで編集できるようにします。

まずは、 `show.html.erb` を修正します。 `turbo_frame_tag` で一部囲みます。

```erb:app/views/users/show.html.erb
<%= turbo_frame_tag @user do %>
  <p style="color: green"><%= notice %></p>
  <%= render @user %>
  <div>
    <%= link_to "Edit this user", edit_user_path(@user) %>
  </div>
<% end %>

<div>
  <%= link_to "Back to users", users_path %>

  <%= button_to "Destroy this user", @user, method: :delete %>
</div>
```

続いて、 `edit.html.erb` も修正します。 一部を `turbo_frame_tag` で囲みます。

```erb:app/views/users/edit.html.erb
<h1>Editing user</h1>

<%= turbo_frame_tag @user do %>
  <%= render "form", user: @user %>
  <div>
    <%= link_to "Show this user", @user %>
  </div>
<% end %>

<div>
  <%= link_to "Show this user", @user %>
  <%= link_to "Back to users", users_path %>
</div>
```

## Rails を実行する

動作を確認するため、Rails を実行します。

```shell
bin/rails s
```

## ブラウザからアクセスする

`http://localhost:3000/users` にアクセスし、User を登録します。次にこのユーザーを表示(http://localhost:3000/users/1 にアクセス)します。
![turbo_frame_tag01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209941/c4954db8-78af-e11f-6804-3f12bfdef200.png)

ここで `Edit this user` をクリックすると、 `turbo_frame_tag` で囲っていた部分だけが置き変わり、編集できるようになります。
URLは変わらず http://localhost:3000/users/1 のままですし、`turbo_frame_tag` で囲まなかった部分は、変わりません。
![turbo_frame_tag02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209941/a3aa4533-91dd-ed4d-e4e2-fa382b774825.png)

実際に値を編集して、 `Update User` ボタンを押します。
![turbo_frame_tag03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209941/f5f0cc4c-8e6f-5790-17c6-421458397aa1.png)

すると、編集した値が反映された状態で詳細画面が表示されます。
![turbo_frame_tag04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209941/d1264b1c-67bc-f880-98b6-2f3ac539190f.png)

詳細画面を表示して編集して詳細画面を再度表示するまでの間、ブラウザのURLは http://localhost:3000/users/1 のままで、ページ全体は遷移しません。
`turbo_frame_tag` で囲った部分だけが動的に変化します。

## まとめ

今回は、 `turbo_frame_tag` を試しました。
実際のプロジェクトで使った場合に、何が課題になるのか、できないことは何なのか、どういう場面で使うべきなのか、コントローラやルーティングはどうするのが良いのか、などなど、筆者には、まだまだ、知見が足りません。
ですが、Javascript を1行も書かないで、SPA を作れる可能性が十分にあり、Ruby on Rails におけるフロントエンドの開発が変わるのではないかと本当にワクワクしています。

試したコードは、 https://github.com/suketa/rails_sandbox/tree/try_rails7_turboframe になります。

## 参考情報

- [Turbo](https://github.com/hotwired/turbo-rails)
- [Single attribute in-place editing with Rails and Turbo](https://nts.strzibny.name/single-attribute-in-place-editing-turbo/)
  - こちらでは、controller と view を新しく追加して、1つの項目だけ編集できるようにする例を解説しています。