Respond with inline turbo_stream or render turbo_stream.erb

Hello,

I would like to know what the vision behind format.turbo_stream was when it was developed.

We can do two things:

Inline

def create
  @message = Message.create!(params.require(:message).permit(:content))
  respond_to do |format|
    format.turbo_stream: [
      turbo_stream.append "messages", @messages,
      turbo_stream.replace "new_message", partial: "new_message", locals: { room: @room }
    ]
    format.html { redirect_to messages_url }
  end
end

Render create.turbo_stream.erb

def create
  @message = Message.create!(params.require(:message).permit(:content))
  respond_to do |format|
    format.turbo_stream
    format.html { redirect_to messages_url }
  end
end

# <% app/views/messages/create.turbo_stream.erb %>
<%= turbo_stream.append "messages", @message %>

<%= turbo_stream.replace "new_message" do %>
  <%= render partial: "new_message", locals: { room: @room } %>
<% end %>

We were having a discussion in the office on which should we use and that in:

There is no mention in rendering a .turbo_stream.erb template.

On the other hand in the turbo-rails gem there is:

Which suggests that we should be using format.turbo_stream to render partials.

Could you give a little bit of light what the ideal ā€˜by the book’ way is and potentially add it in the turbo-rails docs in order for people to write consistent rails code.

Cheers.
Michael.

3 Likes

I can’t speak to what the ā€œby the bookā€ way should be, but I greatly prefer the inline method vs. the partial method. If the updates are referencing objects and other partials only, there’s no need for a specific stream template because you’re not adding any bespoke HTML in that template. (And if you are…hmm, that doesn’t feel right to me.) So I’m glad the inline method does exist, and that’s what I would advocate for.

In response to this same question about inline vs template turbo-streams, DHH responded:

While this [inline] is possible, it’s discouraged. I’d rather we don’t promote this. You can of course always do whatever you want, but in my style guide, this is much worse than using a template.

see: Syntax for returning multiple turbo streams Ā· Issue #77 Ā· hotwired/turbo-rails Ā· GitHub

3 Likes

I would just like to point out that syntax is a little bit different.

      respond_to do |format|
        format.turbo_stream do
          render(
            turbo_stream: [
              turbo_stream.replace(...),
              turbo_stream.replace(...)
            ])
        end
      end