Using devise (3.2.2)
Using rails (4.0.2)
Working on developing an API which only has the need for only certain routes. I have the following in my routes.rb
:
devise_for :users, path: '/users', controllers: {
sessions: 'v1/custom_devise/sessions',
passwords: 'v1/custom_devise/passwords'
}
Great! Now we have all these routes:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) v1/custom_devise/sessions#new
user_session POST /users/sign_in(.:format) v1/custom_devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) v1/custom_devise/sessions#destroy
user_password POST /users/password(.:format) v1/custom_devise/passwords#create
new_user_password GET /users/password/new(.:format) v1/custom_devise/passwords#new
edit_user_password GET /users/password/edit(.:format) v1/custom_devise/passwords#edit
PATCH /users/password(.:format) v1/custom_devise/passwords#update
PUT /users/password(.:format) v1/custom_devise/passwords#update
But I do not want or need these routes:
new_user_session GET /users/sign_in(.:format) v1/custom_devise/sessions#new
new_user_password GET /users/password/new(.:format) v1/custom_devise/passwords#new
edit_user_password GET /users/password/edit(.:format) v1/custom_devise/passwords#edit
So I thought I will just create my own routes as per the documentation. So I changed my routes.rb
:
devise_scope :user do
post '/users/sign_in' => 'custom_devise/sessions#create', as: :user_session
delete '/users/sign_out' => 'custom_devise/sessions#destroy', as: :destroy_user_session
post '/users/password' => 'custom_devise/passwords#create', as: :user_password
put '/users/password' => 'custom_devise/passwords#update', as: nil
patch '/users/password' => 'custom_devise/passwords#update', as: nil
end
Now my routes look perfect, just the way I want them:
Prefix Verb URI Pattern Controller#Action
user_session POST /users/sign_in(.:format) v1/custom_devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) v1/custom_devise/sessions#destroy
user_password POST /users/password(.:format) v1/custom_devise/passwords#create
PUT /users/password(.:format) v1/custom_devise/passwords#update
PATCH /users/password(.:format) v1/custom_devise/passwords#update
But now my requests fail, with:
AbstractController::ActionNotFound:
Could not find devise mapping for path "/users/sign_in".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
get "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
@request.env["devise.mapping"] = Devise.mappings[:user]
I have tried many variations, to no avail.
UPDATE: This may be overkill, but here is an sample example app demonstration this. Not sure if I am doing something wrong or if this might be a devise bug.
Sample App: https://github.com/michaelirey/devise_weird
Devise allows you to separate your users into different "scopes" such as "admin" and "member", the effect of this is that you get a set of routes, controllers and views for each scope.
Devise is an excellent authentication system made for Rails that allows us to easily drop-in User functionality into our project. Add Devise to your Gemfile and run bundle install.
You are missing the GET for the sign in action that shows you the login form.. you only have the session creation, fix it like such (you :
devise_scope :user do
get '/users/sign_in' => 'custom_devise/sessions#new', as: :new_user_session
post '/users/sign_in' => 'custom_devise/sessions#create', as: :user_session
delete '/users/sign_out' => 'custom_devise/sessions#destroy', as: :destroy_user_session
post '/users/password' => 'custom_devise/passwords#create', as: :user_password
put '/users/password' => 'custom_devise/passwords#update', as: nil
patch '/users/password' => 'custom_devise/passwords#update', as: nil
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With