<% highlight = local_assigns.fetch(:highlight, false) %> <tr class="group p-2" id="<%= dom_id(todo) %>"> <td class="<%= 'highlight-on-appear' if highlight %> p-2 border-gray-400 border-t group-[:first-child]:border-none"> <div class="flex"> <div class="flex grow items-center"> <%= render 'like_button', todo: %> <%= todo.title %> <!-- ... --> </div> <!-- ... --> </div> </td> </tr>
app/views/todos/_todo.html.erb partialですrender 'like_button', todo:で「いいね」ボタンを表示しています。<% todo = local_assigns.fetch(:todo) %> <%= tag.div id: dom_id(todo, :like_button), class: "flex items-center w-16" do %> <%= label_tag nil, class: "group flex cursor-pointer select-none" do %> <% if todo.liked_by?(current_user) %> <%= button_to todo_likes_path(todo), method: :post, class: "cursor-pointer" do %> <%= liked_icon %> <% end %> <% else %> <%= button_to todo_likes_path(todo), method: :post, params: { like: "1" }, class: "cursor-pointer" do %> <%= unliked_icon %> <% end %> <% end %> <div> : <span><%= todo.likes_count %></span> </div> <% end %> <% end %>
tag.div id: dom_id(todo, :like_button)のところでIDをつけています。class Todos::LikesController < ApplicationController # ... def create sleep 1 if params[:like] @todo.like_by! current_user else @todo.unlike_by! current_user end if request.variant.drive? return redirect_to todos_path end end private def set_todo @todo = Todo.find(params[:todo_id]) end end
コントローラはTurbo Driveのものと同じです。ただしrequest.variant.drive?はfalseを返しますので、app/views/todos/likes/create.turbo_stream.erb(下記)をテンプレートとしたレスポンスを返します。
<%= turbo_stream.replace dom_id(@todo, :like_button) do %> <%= render partial: "todos/like_button", locals: { todo: @todo } %> <% end %>
app/views/todos/likes/create.turbo_stream.erbでは “todos/like_button"のpartialを返します。今回は"streams"のvariantを使いますので、app/views/todos/_like_button.html+streams.erbを返します