Challenge 2: A Turbo Stream Response — Solution
# app/controllers/comments_controller.rb
def destroy
@comment = Comment.find(params[:id])
@comment.destroy
respond_to do |format|
format.turbo_stream # renders destroy.turbo_stream.erb automatically
end
end
# app/views/comments/destroy.turbo_stream.erb
<%= turbo_stream.remove "comment_#{@comment.id}" %>
# app/views/comments/_comment.html.erb must render each comment wrapped
# with a matching id for remove to find the right element:
=begin
Notes:
- respond_to with format.turbo_stream follows the exact same Rails
convention as an HTML or JSON respond_to block (rails2-5) -- Rails
automatically looks for a view named destroy.turbo_stream.erb matching
the action name, no manual template lookup required.
- turbo_stream.remove takes just a DOM element id string, unlike append
(which also needs a partial/locals to render new content) -- remove has
nothing to render, only an element to take out of the page.
- The id passed to remove ("comment_#{@comment.id}") must match the id the
comment partial actually rendered with on the page, or Turbo has nothing
to find and the remove silently does nothing.
- @comment.destroy happens before the turbo_stream response is rendered,
so by the time the client removes the element from the DOM, the
corresponding database row is already gone too.
=end