Reputation: 31
I have an issue with a delete method not triggering the redirect specified in my controller. I am using Rails 7.0.4 and Ruby 3.1.2
employees_controller.rb
def destroy
@employee.destroy
respond_to do |format|
format.html { redirect_to root_path, notice: "Employee was deleted" }
format.turbo_stream { flash.now[:notice] = "Employee was deleted" }
end
end
_employees.html.erb
<%= turbo_frame_tag "employees" do %>
<%= render employees %>
<% end %>
_employee.html.erb
<div id="<%= dom_id employee %>">
<div class="index bg-white dark:bg-gray-900 px-4 md:px-10">
<div class="overflow-x-auto">
<table class="w-full whitespace-nowrap">
<tbody>
<tr tabindex="0" class="focus:outline-none text-sm leading-none text-gray-600 dark:text-gray-200 h-16">
<td class="w-1/2">
<div class="flex items-center">
<div class="w-10 h-10 rounded-sm flex items-center justify-center">
<p class="text-xs font-bold leading-3 text-white"><%= gravatar_for employee %></p>
</div>
<div class="pl-2">
<p><%= link_to "#{employee.first_name} #{employee.last_name}", employee_path(employee, employee), class: "text-sm font-medium leading-none text-gray-800 dark:text-white"%></p>
<p class="text-xs leading-3 text-gray-600 dark:text-gray-200 mt-2"><%= employee.email %></p>
</div>
</div>
</td>
<td class="pl-8">
<p>
<%= link_to "View", employee_path(employee, employee), type: "button",
class: "inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg
focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out" %>
</p>
</td>
<td class="pl-8">
<p>
<%= link_to "Edit", edit_employee_path(employee, employee), type: "button",
class: "inline-block px-6 py-2.5 bg-yellow-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-yellow-700 hover:shadow-lg
focus:bg-yellow-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-yellow-800 active:shadow-lg transition duration-150 ease-in-out" %>
</p>
</td>
<td class="pl-8">
<p>
<%= link_to "Delete", employee_path(employee), data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }, type: "button",
class: "inline-block px-6 py-2.5 bg-red-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-red-700 hover:shadow-lg
focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out" %>
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
I even recorded a quick Loom showcasing the lack of redirect in action: https://www.loom.com/share/e2c333e54fb84b9193c07b54a3546d54
Upvotes: 1
Views: 1174
Reputation: 2339
EDIT
The answer below is opinionated: I assumed you want to use Turbo frames/streams as you enclose your employees in an "employees" turbo frame, and also you have a turbo_stream method in your controller.
Though it doesn't clearly answer your question. And the fact the URL changes when you click on an employee is something to investigate.
Please share your show.html.erb
file in order to get a better picture.
You are not using Turbo Frame with the single page principle in mind.
You have only a single frame at the moment called "employees". All your employees cards are added as plain HTML. Basically adding a dom_id on a div will have no effect as Turbo (whether through an HTML response or a Turbo_stream response) cannot remove any DOM element which is not a turbo Frame.
When you delete a card from the index page, what I think happens is that the index pages is replayed and the flash happens. Just like the old Rails pre-Turbo era.
In your controller you don't say if you have a destroy.turbo_stream.erb
file but I doubt that. If you had it would have no effect anyway.
Now, regarding your show view, it is interesting because the code seems to not be matching your _employee.html.erb
partial. Then you have probably some custom HTML in show.html.erb
in order to make a more detailed profile. But this detailed profile may not have a turbo frame either.
What to do
In your _employee.html.erb
file, replace <div id="<%= dom_id employee %>">
by <%= turbo_frame_tag dom_id(employee) do %>
and
replace the closing </div>
by a closing <% end %>
. All your
employees will have their own turbo frame.
create a destroy.turbo_stream.erb
file and add <%= turbo_stream.remove "employee_#{@employee.id}" %>
inside. This means that instead of reloading your index page, or basically navigating your app with new pages being loaded, the right Turbo frame is deleted from the view. You basically have not left your view. The call to employees#destroy has been done async by Turbo.
Now regarding your detailed view :
It seems it all lives in show. It would be better to create another partial called _detailed_employee.html.erb
and add the same turbo frame <%= turbo_frame_tag dom_id(employee) %>
When you destroy it, it should be removed from the DOM the same way as detailed above.
Note that when you delete this card in show, your show view will be left empty. Which is probably not what you want. So your probably have to tune your logic later.
Also your code is hybrid at the moment: you leverage both Turbo frames (SPA concept) and classic navigation. It is all fine and you will probably find the right balance later. But it is not easy even for experienced programmers to wrap their mind around the concept of actually visiting a page the HTTP way and doing some async requests with Turbo.
I hope my post doesn't have too many errors and that it will help you.
PS: nearly forgot: for your links, you don't need to repeat employee twice employee_path(employee, employee)
it makes the path in navbar looks like employees/14.14
Rails understand that the ID param is 14, but the second 14 is not needed.
Upvotes: 1