devise icon indicating copy to clipboard operation
devise copied to clipboard

Incorrect default route for registration#create

Open duhlin opened this issue 3 years ago • 4 comments

Environment

  • Ruby 3.0.3
  • Rails 7.0.1
  • Devise 4.8.1

Current behavior

With the default routing options, the url to get the form to sign_up is: resource/sign_up. This returns a form which default action is to POST to resource.

In case of validation errors on this form, the url of the browser is then resource. If the user refreshes his browser, he get a 404 error.

Expected behavior

In case of validation errors, if the user refreshes, he should get the form from /resource/sign_up

Note:

The expected behavior is the correct one for the sign_in form. (Both get and post actions target /resource/sign_in)

This can be fixed for the sign_up form with:

module ActionDispatch::Routing
  class Mapper
    def devise_registration(mapping, controllers) #:nodoc:
      path_names = {
        new: mapping.path_names[:sign_up],
        edit: mapping.path_names[:edit],
        cancel: mapping.path_names[:cancel]
      }

      options = {
        only: [:edit, :update, :destroy],
        path: mapping.path_names[:registration],
        path_names: path_names,
        controller: controllers[:registrations]
      }

      # force :create to be at same url than :new
      resource :registration, options do
        get :new, path: mapping.path_names[:sign_up], as: 'new'
        post :create, path: mapping.path_names[:sign_up], as: 'create'
        get :cancel
      end
    end
  end
end

duhlin avatar Jan 30 '22 14:01 duhlin

I had problems creating the devise views with users. $ rails generate devise:views users

evertonlopesc avatar Feb 02 '22 02:02 evertonlopesc

You just need to edit the sign up button of the devise to this:

mvpxtech avatar Feb 19 '22 03:02 mvpxtech

Thanks @mvpxtech. I'm not sure to understand the relation with Turbo/Turbolinks here.

Unless I'm mistaken, when a form is submitted, the location of the browser changes to the url of the action of the form.

The default behavior of the registration controller called by the POST is either to:

  • render the form with the list of errors when there are some errors
  • or to redirect to another url when the registration is successful.

The consequence is that when there is an error, the location of the browser is set to /resource. Unfortunately, there is no 'GET' route by default for this path. A refresh of the page doesn't work as expected: 404 instead of the login form.

The same definition of the routes for sign_up than the ones for sign_in would fix the problem.

duhlin avatar Feb 25 '22 13:02 duhlin

@duhlin There is a breaking change in Rails 7: Invalid form submissions have to return a 422 status code for Turbo Drive to replace the

of the page and display the form errors. The alias for the 422 status code in Rails is :unprocessable_entity. That's why, since Ruby on Rails 7, the scaffold generator adds status: :unprocessable_entity to #create and #update actions when the resource couldn't be saved due to an invalid form submission.

mvpxtech avatar Feb 28 '22 07:02 mvpxtech

The main branch should contain all that's necessary for fully working with Turbo now, which should fix this. A new version will be released soon, but feel free to test it out from the main branch in the meantime, and report back on any issues. Thanks.

carlosantoniodasilva avatar Feb 09 '23 21:02 carlosantoniodasilva