Form redirects not working as expected

Hey Andrew,
I saw the same problem for one of the forms that required me to just redirect to a new page.

From what I saw in the code, Turbo will only redirect on GET requests. I agree with you that this is a pretty strange case and we definitely need a way to say in our form itself that if we get redirected in response, we can do a full redirect. If someone can help with that, would be great!

For now, I did a hack with stimulus. I can share my

import { Controller } from "stimulus"
import { Turbo } from "@hotwired/turbo-rails"

export default class extends Controller {
  static targets = [ "form" ]

  initialize() {
    this.listener = this.listener.bind(this)
  }

  connect() {
    this.formTarget.addEventListener("turbo:submit-end", this.listener)
  }

  disconnect() {
    this.formTarget.removeEventListener("turbo:submit-end", this.listener)
  }

  listener(event) {
    const fetchResponse = event.detail.fetchResponse
    if (fetchResponse && fetchResponse.response.status === 201) {
      Turbo.visit(fetchResponse.response.headers.get('Url'))
    }
  }
}

Then in my .erb template I do this for forms where full redirect is required:

<%= turbo_frame_tag 'banana_form' do %>
 <%= form_with url: bananas_path, data: { controller: 'redirect-on-created', redirect_on_created_target: 'form' } do |f| %>
   <%= f.submit 'Go Bananas' %>
  <% end %>
<% end %>

In this case, if your controller will do something like this:

def create
    @banana = Banana.new(banana_params)
    if @banana.valid?
      head :created, url: bananas_path
    else
      render turbo_stream: turbo_stream.replace('banana_form', partial: 'form')
    end
end

So if you will have errors - it will replace your form with a fresh version of partial, if not it will return info for redirect and Turbo will do the job.

I know it’s probably hacky way and I would love Hotwire docs to answer this question for me, but for now, it’s working just fine.

1 Like