初めに
個人的に運用中のRailsアプリ(7.0.8)をRails 8.0.2にアップデートし、Hotwireを導入した手順を簡潔にまとめる。
Rails8へのアップデート
Gemfile修正
Gemfile
- gem "rails", "~> 7.0.8"
+ gem "rails", "~> 8.0.2"
docker compose build
docker compose run web bundle update rails
docker compose build
docker compose run web bundle install --gemfile Gemmfile
config/ 以下のファイルが新しいテンプレートに更新されるので、必要に応じて修正。
起動
docker compose up --build
エラー修正
- Rails 8から enum の書き方が変更になった。
- enum role: { user: 0, admin: 1 }
+ enum :role, { user: 0, admin: 1 }
Hotwire
Turbo Drive
app/javascript/application.js に以下を追記。
app/javascript/application.js
import "@hotwired/turbo-rails"
import "controllers"
もし無効化する場合は以下を追記
Turbo.session.drive = false
Turbo Frame化
修正前の画面。ちなみにこのアプリは家庭内でお小遣いを仮想通貨で送金するアプリ。
ここで受け取りボタンを押すとコイン受取画面へ遷移する。ブロックチェーンを使っているが、UIは普通のRailsアプリである。
この受取フォームをTurbo Frame化する。
home/index.html.erb
- <%= link_to "受取", gift_new_transactions_path(user_id: user), class: "btn btn-lg btn-outline-primary" %>
+ <%= turbo_frame_tag "gift_form_#{user.id}" do %>
+ <%= link_to "受取", gift_new_transactions_path(user_id: user), data: { turbo_frame: "gift_form_#{user.id}" }, class: "btn btn-lg btn-outline-primary" %>
+ <% end %>
transactions/gift_new.html.erb
+ <turbo-frame id="gift_form_<%= @transaction.to_user_id %>">
<%= render "gift_form", transaction: @transaction %>
+ </turbo-frame>
上記の修正だけで、画面遷移せずに動的にフォームが表示されるようになる。
実行後にリストを更新する
リストの部分を以下のコードに変更
index.html.erb
- (旧リスト)
+ <turbo-frame id="transactions_list">
+ <%= render partial: "home/transactions_table", locals: { transactions: @transactions } %>
+ </turbo-frame>
以下の二つのファイルを追加
transactions/gift.turbo_stream.erb
<turbo-frame id="gift_form_<%= @transaction.to_user_id %>">
<%= render "gift_form", transaction: @transaction %>
</turbo-frame>
home/_transactions_table.html
<div class="table-responsive">
<table class="table text-right table-hover text-nowrap table-sm">
<thead class="table-light" style="--bs-table-bg: #f5ffff;">
<tr>
<th>日時</th>
<th>種類</th>
<th>対象</th>
<th>タピオカ</th>
<th>メモ</th>
<th>tx</th>
</tr>
</thead>
<tbody>
<% transactions.each do |t| %>
<tr>
<th scope="row" class="text-start"><%= link_to (l t.created_at, format: :default), transaction_path(t[:id]), class: "link-primary" %></th>
<td><%= t.transaction_type_i18n %></td>
<td><%= t.user&.name %> ⇒ <%= t.to_user&.name %></td>
<td><%= t.amount %></td>
<td><%= t.memo %></td>
<td><%= link_to t.txid, "https://testnet-explorer.tapyrus.dev.chaintope.com/tx/#{t.txid}", class: "link-secondary" %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
transactions_controller.rb
def gift
# ...
if @transaction.save
respond_to do |format|
+ format.turbo_stream
format.html { redirect_to transactions_path, notice: "受取が完了しました" }
end
else
# ...エラー処理...
end
end
まとめ
Rails 8 へのアップデートとHotwireの導入で、画面遷移を減らしスムーズな操作が実現できた。