Hotwire Discussion

A form/controller that is used it two places

I have a form that appears in two places pointing to the same controller. Before hotwire that wasn’t a problem because after submitting it would redirect to the correct page in both cases. Now, with hotwire, it needs to update one page, one case, and redirect in the other case.

The controller action looks something like this, simplified:

class InvitationsController < ApplicationController
  def create
    @invitation = Invitation.new(invitation_params)
    @invitation.requester = current_user

    if @invitation.save
      respond_to do |format|
        format.turbo_stream
        format.html { redirect_to invitations_url, notice: "#{@invitation.name} was invited." }
      end 
  end
end

create.turbo_streams.erb looks like this:

<%= turbo_stream.append "invitations", @invitation %>

and invitations/index.html.erb as a turbo-frame with id “invitations”.

The problem is that there’s another page that also calls invitations/create and in that case, what should happen is it should redirect to invitations_url. How should that happen?

I’m inclined to say they should be two different actions (possibly different controllers, even). The way I see it, if you want different to happen then you need different methods (in most cases).

Or if that’s no good (and it may not be!), you could pass an extra param or something in a hidden field and if-else on that.

I’ve been reluctant to use streams in lots of places, because of this sort of scenario.

This is the policy we’ve settled on too.

@dan provides some good suggestions.

Another option might be Disabling Turbo Drive on Specific Forms you want to redirect from.

<form action="/messages" method="post" data-turbo="false">
  ...
</form>

or

<div data-turbo="false">
  <form action="/messages" method="post">
    ...
  </form>
</div>

A disabled turbo form would not create a turbo_stream on submit and your existing controller logic should work.

FYI, that doesn’t work reliably if you are using a Turbo Native adapter ^