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