I'm using the Rails4 branch of devise, and trying to setup some custom routes, so the users sign in via /api/sessions with a POST request. My routes.rb consists of
require 'api_constraints'
MyGuardianAPI::Application.routes.draw do
namespace :api, default: { format: :json } do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
# Setup routes for devise. We don't want EVERYTHING under the /users route
devise_for :users, skip: :all
devise_scope :user do
post "/sessions" => "sessions#create"
delete "/sessions" => "sessions#destroy"
end
resources :locations
end
end
end
When I run rake routes I see what I expect
api_sessions POST /api/sessions(.:format) api/v1/sessions#create {:default=>{:format=>:json}}
DELETE /api/sessions(.:format) api/v1/sessions#destroy {:default=>{:format=>:json}}
api_locations GET /api/locations(.:format) api/v1/locations#index {:default=>{:format=>:json}}
POST /api/locations(.:format) api/v1/locations#create {:default=>{:format=>:json}}
new_api_location GET /api/locations/new(.:format) api/v1/locations#new {:default=>{:format=>:json}}
edit_api_location GET /api/locations/:id/edit(.:format) api/v1/locations#edit {:default=>{:format=>:json}}
api_location GET /api/locations/:id(.:format) api/v1/locations#show {:default=>{:format=>:json}}
PATCH /api/locations/:id(.:format) api/v1/locations#update {:default=>{:format=>:json}}
PUT /api/locations/:id(.:format) api/v1/locations#update {:default=>{:format=>:json}}
DELETE /api/locations/:id(.:format) api/v1/locations#destroy {:default=>{:format=>:json}}
As you can see from routes.rb I've followed the guide on the wiki but instead of it working, I'm getting the error
[Devise] Could not find devise mapping for path "/api/sessions".
The stack trace I am given is
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/devise-6b5988d756d7/app/controllers/devise_controller.rb:84:in `unknown_action!'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/devise-6b5988d756d7/app/controllers/devise_controller.rb:59:in `assert_is_devise_resource!'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/devise-6b5988d756d7/app/controllers/devise_controller.rb:97:in `require_no_authentication'
activesupport (4.0.0) lib/active_support/callbacks.rb:377:in `_run__2930795176805468890__process_action__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.0) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.0.0) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.0.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.0.0) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activerecord (4.0.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.0.0) lib/abstract_controller/base.rb:136:in `process'
actionpack (4.0.0) lib/abstract_controller/rendering.rb:44:in `process'
actionpack (4.0.0) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.0.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.0.0) lib/action_controller/metal.rb:231:in `block in action'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:48:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/mapper.rb:44:in `call'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:71:in `block in call'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `each'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:655:in `call'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/warden-82c46b25d837/lib/warden/manager.rb:35:in `block in call'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/warden-82c46b25d837/lib/warden/manager.rb:34:in `catch'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/warden-82c46b25d837/lib/warden/manager.rb:34:in `call'
rack (1.5.2) lib/rack/etag.rb:23:in `call'
rack (1.5.2) lib/rack/conditionalget.rb:35:in `call'
rack (1.5.2) lib/rack/head.rb:11:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
activerecord (4.0.0) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.0.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
activerecord (4.0.0) lib/active_record/migration.rb:369:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.0.0) lib/active_support/callbacks.rb:373:in `_run__1460217480304294875__call__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/reloader.rb:64:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.0.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.0.0) lib/rails/rack/logger.rb:21:in `block in call'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `block in tagged'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:25:in `tagged'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `tagged'
railties (4.0.0) lib/rails/rack/logger.rb:21:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.2) lib/rack/runtime.rb:17:in `call'
activesupport (4.0.0) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/static.rb:64:in `call'
railties (4.0.0) lib/rails/engine.rb:511:in `call'
railties (4.0.0) lib/rails/application.rb:97:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
rack (1.5.2) lib/rack/content_length.rb:14:in `call'
rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service'
/Users/Aidy/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
/Users/Aidy/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
/Users/Aidy/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
Any clues as to what I've done wrong would be really helpful, or have I stumbled across a bug somehow? I've looked through existing issues, but they don't shed any light on the issue I'm having :(
@pareeohnos can you please try out the 3.0.0.rc version instead of the rails4 branch?
Just switched to 3.0.0.rc and getting the same error :(
OK So I figured out what the issue was. Because of how devise handles being nested inside a namespace, it was changing the scope that it was looking for, so in my case everything is within the api namespace, so when the app is running, devise is using current_api_user instead of the usual current_user and apparently this is also true for devise_scope
So instead of devise_scope :user I needed to use devise_scope :api_user.
I think this should be documented though, as there isn't really much explanation about using devise within a namespace. There is mention of it but not in a lot of detail.
The next issue I'm having is devise is now trying to use the flash within rails which is fine, but my app doesn't need it so it's not loaded in the rack by default. I've added it in manually with
config.middleware.insert_after(Rails::Rack::Logger, ActionDispatch::Flash)
so when I run rake middleware I have
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007fa4ebaa76b0>
use Rack::Runtime
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::Flash
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Warden::Manager
run MyApp::Application.routes
As you can see it's clearly being added to the rack, but I'm still getting the same error
NameError (undefined local variable or method `flash' for #<Api::V1::SessionsController:0x007fca74903a80>):
devise (3.0.0.rc) app/controllers/devise_controller.rb:109:in `require_no_authentication'
activesupport (4.0.0) lib/active_support/callbacks.rb:377:in `_run__3337357092225199612__process_action__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.0) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action'
activesupport (4.0.0) lib/active_support/notifications.rb:159:in `block in instrument'
activesupport (4.0.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.0.0) lib/active_support/notifications.rb:159:in `instrument'
actionpack (4.0.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activerecord (4.0.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.0.0) lib/abstract_controller/base.rb:136:in `process'
actionpack (4.0.0) lib/abstract_controller/rendering.rb:44:in `process'
actionpack (4.0.0) lib/action_controller/metal.rb:195:in `dispatch'
actionpack (4.0.0) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.0.0) lib/action_controller/metal.rb:231:in `block in action'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:80:in `dispatch'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:48:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/mapper.rb:44:in `call'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:71:in `block in call'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `each'
actionpack (4.0.0) lib/action_dispatch/journey/router.rb:59:in `call'
actionpack (4.0.0) lib/action_dispatch/routing/route_set.rb:655:in `call'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/warden-82c46b25d837/lib/warden/manager.rb:35:in `block in call'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/warden-82c46b25d837/lib/warden/manager.rb:34:in `catch'
/Users/Aidy/.rvm/gems/ruby-1.9.3-p125/bundler/gems/warden-82c46b25d837/lib/warden/manager.rb:34:in `call'
rack (1.5.2) lib/rack/etag.rb:23:in `call'
rack (1.5.2) lib/rack/conditionalget.rb:35:in `call'
rack (1.5.2) lib/rack/head.rb:11:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
activerecord (4.0.0) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.0.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
activerecord (4.0.0) lib/active_record/migration.rb:369:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.0.0) lib/active_support/callbacks.rb:373:in `_run__990807079193913570__call__callbacks'
activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/reloader.rb:64:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/flash.rb:241:in `call'
railties (4.0.0) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.0.0) lib/rails/rack/logger.rb:21:in `block in call'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `block in tagged'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:25:in `tagged'
activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `tagged'
railties (4.0.0) lib/rails/rack/logger.rb:21:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.2) lib/rack/runtime.rb:17:in `call'
activesupport (4.0.0) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
actionpack (4.0.0) lib/action_dispatch/middleware/static.rb:64:in `call'
railties (4.0.0) lib/rails/engine.rb:511:in `call'
railties (4.0.0) lib/rails/application.rb:97:in `call'
rack (1.5.2) lib/rack/lock.rb:17:in `call'
rack (1.5.2) lib/rack/content_length.rb:14:in `call'
rack (1.5.2) lib/rack/handler/webrick.rb:60:in `service'
/Users/Aidy/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
/Users/Aidy/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
/Users/Aidy/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
Adding the flash middleware without the session and cookies middleware is not going to work. You'd need to add them all.
Is there some way I can stop devise from using flash then? It would be nice to be able to disabled the use of flash if desired. I can try and patch this if you like?
I think you can implement def flash in your application to return the same flash as rails, just don't persist it in the section.
Ah perfect! Just threw this in an initialiser (in case anyone else has a similar problem)
def flash
Flash.new
end
class Flash
def []=(k, v)
end
def [](k)
end
def alert=(message)
end
def notice=(message)
end
end
Most helpful comment
OK So I figured out what the issue was. Because of how devise handles being nested inside a namespace, it was changing the scope that it was looking for, so in my case everything is within the
apinamespace, so when the app is running, devise is usingcurrent_api_userinstead of the usualcurrent_userand apparently this is also true fordevise_scopeSo instead of
devise_scope :userI needed to usedevise_scope :api_user.I think this should be documented though, as there isn't really much explanation about using devise within a namespace. There is mention of it but not in a lot of detail.
The next issue I'm having is devise is now trying to use the flash within rails which is fine, but my app doesn't need it so it's not loaded in the rack by default. I've added it in manually with
so when I run
rake middlewareI haveAs you can see it's clearly being added to the rack, but I'm still getting the same error