Redirect on form update

I have a form that POSTs to an update method. When successfully updated it should redirect_to another page. It works with HTML but with turbo_stream enabled it appends the redirected page content and doesn’t updated the page location. How do I get it to replace the redirected content correctly without disabling turbo_stream?

Take a look at How to redirect from a form that is inside a turbo frame? - #2 by rockwell

Thanks. I’m surprised this requires a workaround as it’s such a basic design pattern for forms. It’s also surprising that with turbo_stream on by default it leaves so many forms broken with no official docs explaining why or how to work around it.

1 Like

Hi!

If I’m not mistaken there is a better way, a native way to do it, using data_turbo_farme: "_top" or "nativation", have you tried it?

I had a quick go and that didn’t work for me. Maybe if I understood it better I’d be able to get it to work. Struggling to learn Turbo.

Here is a code snippet of what I think might work:

There are two forms, and they are both inside a <turbo-frame/>. The first form, if submitted, will cause turbo to replace both forms with the new HTML, but the second form has a data: { turbo_frame: "_top" } attribute to prevent this and instead redirect_to.

Is that what you wanted to do?

# new.html.erb
<turbo-frame id="new_article">
    <div>
      <div>
        <h2>Submitting this form will cause turbo to replace the entire container<h2>

        <%= form_with model: @article do |form| %>
          <div>
            <%= form.label :title %><br>
            <%= form.text_field :title %>
          </div>

          <div>
            <%= form.label :body %><br>
            <%= form.text_area :body %>
          </div>

          <div>
            <%= form.submit %>
          </div>
        <% end %>
      </div>
      <div>
        <h2>Submitting this form will break out of turbo-frame and redirect<h2>

        <%= form_with model: @article, data: { turbo_frame: "_top" } do |form| %>
          <div>
            <%= form.label :title %><br>
            <%= form.text_field :title %>
          </div>

          <div>
            <%= form.label :body %><br>
            <%= form.text_area :body %>
          </div>

          <div>
            <%= form.submit %>
          </div>
        <% end %>
      </div>
    </turbo-frame>

Both forms map to the :create action, that renders this erb:

# show.html.erb
<turbo-frame id="new_article">
  <h1><%= @article.title %></h1>
  <p><%= @article.body %></p>
</turbo-frame>