Rails: Hotwire: turbo-frameによるインライン編集

目的

スキャフォールドのEditをインラインで編集できるようにする。

環境

Ruby 2.7.2
Rails 6.1.3.1
Turbo 7.0.0-beta.5

アプリ、スキャフォールドとシードを用意する。

rails new hw_inline_edit --skip-javascript
cd hw_inline_edit
tmux
bin/bundle remove jbuilder
bin/bundle add hotwire-rails
bin/rails hotwire:install
bin/bundle install
bin/rails g scaffold message title content:text
bin/rails db:migrate
# db/seeds.rb
1.upto(3) do |i|
  Message.create!(title: "Title#{i.to_s}", content: "Content#{i.to_s}")
end
bin/rails db:seed
# config/routes.rb
Rails.application.routes.draw do
  resources :messages
  root to: 'messages#index'
end

tableタグを削除する。

tableタグをMessageの繰り返しに変更する。
Destroyが機能するようにbutton_toに変更する。
参考:Rails: Hotwire: button_to(delete)の見た目をlink_toに変更する

tableタグを削除する。

# app/views/messages/index.html.erb
<p id="notice"><%= notice %></p>

<h1>Messages</h1>
<% @messages.each do |message| %>
  <p>
    <strong>Title:</strong>
    <%= message.title %>
  </p>
  <p>
    <strong>Content:</strong>
    <%= message.content %>
  </p>
  <p>
    <%= link_to 'Show', message %> |
    <%= link_to 'Edit', edit_message_path(message) %>
    <%= button_to 'Destroy', message, method: :delete %>
  </p>
  <br>
 <% end %>

 <br>

<%= link_to 'New Message', new_message_path %>

部分テンプレートに移行する。

_messageファイルを作成してindex.html.erbからrenderする。

# app/views/messages/_message.html.erb
<p>
  <strong>Title:</strong>
  <%= message.title %>
</p>
<p>
  <strong>Content:</strong>
  <%= message.content %>
</p>
<p>
  <%= link_to 'Show', message %> |
  <%= link_to 'Edit', edit_message_path(message) %>
  <%= button_to 'Destroy', message, method: :delete %>
</p>
<br>
# app/views/messages/index.html.erb
<p id="notice"><%= notice %></p>

<h1>Messages</h1>

<%= render @messages %>

<br>

<%= link_to 'New Message', new_message_path %>

turbo_frame_tagを追加する。

全体をturbo_frame_tagで囲む。
ShowリンクはTurboを使わないので無効にする。
Editリンクはturbo_frame_tagを含むビューが返されることを期待する。

turbo_frame_tagを追加する。

# app/views/messages/_message.html.erb
<%= turbo_frame_tag message do %>
  <p>
    <strong>Title:</strong>
    <%= message.title %>
  </p>
  <p>
    <strong>Content:</strong>
    <%= message.content %>
  </p>
  <p>
    <%= link_to 'Show', message, 'data-turbo': false %> |
    <%= link_to 'Edit', edit_message_path(message) %>
    <%= button_to 'Destroy', message, method: :delete %>
  </p>
  <br>
<% end %>

インライン編集を可能にする。

render 'form'をturbo_frame_tagで囲む。
updateでredirect_toせずに_messageをrenderする。

# app/views/messages/edit.html.erb
<h1>Editing Message</h1>

<%= turbo_frame_tag @message do %>
  <%= render 'form', message: @message %>
<% end %>

<%= link_to 'Show', @message %> |
<%= link_to 'Back', messages_path %>
# app/controllers/messages_controller.rb
  def update
    if @message.update(message_params)
      render '_message', locals: { message: @message }
    else
      render :edit
    end
  end

以上です。

この記事が気に入ったらサポートをしてみませんか?