Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Unexpected missing paths with multiple `devise_for` blocks #1933

Closed
fj opened this Issue · 8 comments

2 participants

@fj
fj commented

I have this in my config/routes.rb:

  devise_for :users,
    :controllers => {
      :sessions  => "sessions",
      :passwords => "passwords"
    }

  devise_for :users,
    :path_prefix => '/partners/:partner_id',
    :controllers => {
      :sessions  => "sessions",
      :passwords => "passwords"
    }

This generates the paths I might expect:

    new_user_session GET    /users/sign_in(.:format)                            sessions#new
        user_session POST   /users/sign_in(.:format)                            sessions#create
destroy_user_session DELETE /users/sign_out(.:format)                           sessions#destroy
    new_user_session GET    /partners/:partner_id/users/sign_in(.:format)       sessions#new
                     POST   /partners/:partner_id/users/sign_in(.:format)       sessions#create
destroy_user_session DELETE /partners/:partner_id/users/sign_out(.:format)      sessions#destroy

Unfortunately, the routes have overlapping (there's two new_user_session paths) or missing names (there's no user_session POST path for the partners path prefix), so I get errors like:

ActionController::RoutingError (No route matches {:action=>"new", :controller=>"sessions"}):

when invoking the routes in my views:

%li= link_to 'Sign Up', new_user_path
%li= link_to 'Sign In', new_user_session_path

I'm using Devise 2.1.0 and Rails 3.2.6.

@fj
fj commented

I tried searching for terms like "multiple devise_for blocks" in the GitHub issues, on the mailing list, and in the wiki, but didn't discover anything that seemed to be relevant.

@josevalim
Owner

Indeed that's not going to work. The best woud be to choose one of the two blocks to be your canonical routes and then manually define additional routes for the extra ones you need.

@josevalim josevalim closed this
@fj
fj commented

Thanks @josevalim. Is there a canonical "paste this to replicate the routes Devise would have generated" block I can use in my config/routes.rb?

I'm thinking something like

resources :users do
  collection do
    get :sign_in
    post :sign_in
    delete :sign_out
  end
end
resources :sessions
resources :passwords

but I want to make sure I covered all the bases.

@josevalim
Owner

Well, I wouldn't do that still, but anyway you can find the information you asked in this file:

https://github.com/plataformatec/devise/blob/master/lib/devise/rails/routes.rb#L351

@fj
fj commented

Well, I wouldn't do that ...

Ah, okay. I thought that's what you were essentially suggesting when you said "[you should] manually define additional routes for the extra ones you need".

Can you clarify what your recommendation is if I need to generate both sets of paths?

@josevalim
Owner

Can you clarify what your recommendation is if I need to generate both sets of paths?

That's the point. I would try to not need both sets of paths. ;) But if you definitely have to, there is no other option.

@fj
fj commented

Gotcha. Thanks for the link; I'll use this as a workaround for now.

Can you elaborate a bit on what makes it impossible/difficult for Devise to support multiple blocks in this way? I'd be willing to write a pull request if you think there's merit in supporting that use case.

@josevalim
Owner

We kind of did it but since Devise cannot possibly support all set of conditions (constraints, path prefix, name prefix and so on), we have removed and simply said asked users to not nest it. Note that there is a :singular option you can pass to devise_for, but that also changes the warden scope name. If you want to send a pull request that supports :as besides :singular only to modify the named helpers, I would gladly accept that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.