heartcombo / devise

Flexible authentication solution for Rails with Warden.
http://blog.plataformatec.com.br/tag/devise/
MIT License
23.95k stars 5.55k forks source link

Missing route path_names for proper translation #5691

Open jamesst20 opened 4 months ago

jamesst20 commented 4 months ago

Environment

Current behavior

When I update my path_names, the POST/DELETE/PATCH routes ends up to the root_path / and I don't like that all.

    devise_for(
      :users,
      path: "",
      path_names: { 
        sign_in: "sign_in", sign_out: "sign_out", password: "user/password", confirmation: "user/confirmation",
        registration: "", sign_up: "sign_up", cancel: "user/cancel", edit: "user/edit" 
      }
  )
cancel_user_registration_en GET    /en/user/cancel(.:format)
cancel_user_registration_fr GET    /user/cancel(.:format)
   new_user_registration_en GET    /en/signup(.:format)
   new_user_registration_fr GET    /inscription(.:format)
  edit_user_registration_en GET    /en/user/edit(.:format)
  edit_user_registration_fr GET    /user/edit(.:format)
       user_registration_en PATCH  /en
       user_registration_fr PATCH  /
                            PUT    /en
                            PUT    /
                            DELETE /en
                            DELETE /
                            POST   /en
                            POST   /

Expected behavior

cancel_user_registration_en GET    /en/user/cancel(.:format)  
cancel_user_registration_fr GET    /utilisateur/cancel(.:format)
new_user_registration_en GET    /en/signup(.:format)
new_user_registration_fr GET    /inscription(.:format)
edit_user_registration_en GET    /en/user/edit(.:format)
edit_user_registration_fr GET    /utilisateur/edit(.:format)
user_registration_en PATCH  /en/signup(.:format)
user_registration_fr PATCH  /inscription(.:format)
                     PUT    /en/signup(.:format)
                     PUT    /inscription(.:format)
                     DELETE /en/signup(.:format)
                     DELETE /inscription(.:format)
                     POST   /en/signup(.:format)
                     POST   /inscription(.:format)

Note

If I switch my routes for registration: "", sign_up: "sign_up" instead I will get

             cancel_user_registration_en GET    /en/signup/user/cancel(.:format)                                                                  users/registrations#cancel {:locale=>"en"}
             cancel_user_registration_fr GET    /inscription/user/cancel(.:format)                                                                users/registrations#cancel {:locale=>"fr"}
                new_user_registration_en GET    /en/signup(.:format)                                                                              users/registrations#new {:locale=>"en"}
                new_user_registration_fr GET    /inscription(.:format)                                                                            users/registrations#new {:locale=>"fr"}
               edit_user_registration_en GET    /en/signup/user/edit(.:format)                                                                    users/registrations#edit {:locale=>"en"}
               edit_user_registration_fr GET    /inscription/user/edit(.:format)                                                                  users/registrations#edit {:locale=>"fr"}
                    user_registration_en PATCH  /en/signup(.:format)                                                                              users/registrations#update {:locale=>"en"}
                    user_registration_fr PATCH  /inscription(.:format)                                                                            users/registrations#update {:locale=>"fr"}
                                         PUT    /en/signup(.:format)                                                                              users/registrations#update {:locale=>"en"}
                                         PUT    /inscription(.:format)                                                                            users/registrations#update {:locale=>"fr"}
                                         DELETE /en/signup(.:format)                                                                              users/registrations#destroy {:locale=>"en"}
                                         DELETE /inscription(.:format)                                                                            users/registrations#destroy {:locale=>"fr"}
                                         POST   /en/signup(.:format)                                                                              users/registrations#create {:locale=>"en"}
                                         POST   /inscription(.:format)                                                                            users/registrations#create {:locale=>"fr"}

and these routes like /en/signup/user/edit feels more like a user profile editing than something related to the registration.

Proposal

https://github.com/heartcombo/devise/blob/main/lib/devise/rails/routes.rb#L406

# (Non edited snipped to help understand)
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: [:new, :create, :edit, :update, :destroy],
          path: mapping.path_names[:registration],
          path_names: path_names,
          controller: controllers[:registrations]
        }

        resource :registration, options do
          get :cancel
        end
      end

Either fix the gem so that the create/update match the route of mapping.path_names[:sign_up] and mapping.path_names[:edit] or add extra path_names to configure the create/update path names.

Another solution would be to extract non-related registration actions to a new controller like "profile controller"

I'm actually suprised nobody ever came up with this. Am I doing something wrong?