class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.new(comment_params.merge(author: current_member))
if @comment.save
respond_to do |format|
format.turbo_stream
format.html { redirect_to @post, notice: 'Comment posted.' }
end
else
respond_to do |format|
format.turbo_stream { render :create, status: :unprocessable_entity }
format.html { render 'posts/show', status: :unprocessable_entity }
end
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
end
<% if @comment.persisted? %>
<%= turbo_stream.prepend "post_#{@post.id}_comments", partial: "comments/comment", locals: { comment: @comment } %>
<%= turbo_stream.replace "new_comment", partial: "comments/form", locals: { post: @post, comment: Comment.new } %>
<%= turbo_stream.update "flash", partial: "shared/flash" %>
<% else %>
<%= turbo_stream.replace "new_comment", partial: "comments/form", locals: { post: @post, comment: @comment } %>
<% end %>
A good Hotwire endpoint responds to both Turbo and non-Turbo clients. Use respond_to and render a turbo stream that prepends the new record and updates flash/errors, while keeping an HTML fallback for crawlers, redirects, and manual testing.