I am working on an existing web application that uses Rails 3 and Devise. At the moment, my task is to add the JSON API to the application. I created a Mobile :: SessionController (<Devise :: SessionsController) that implements '#create' with a response only to the data.
The problem is routing. Right now, the relevant parts of the .rb routes are as follows:
devise_for :users, :controllers => {:sessions => 'sessions',
:registrations => 'registrations'}
as :user do
get "/login" => "devise/sessions#new"
get "/logout" => "devise/sessions#destroy", :as => :logout
post '/signup' => 'registrations#signup', :as => :signup
end
namespace :api do
namespace :user do
devise_for :users, :controllers => {:sessions => 'mobile/sessions'},
skip: :all
devise_scope :user do
post 'login' => 'mobile/sessions#create'
end
...
The data endpoint is located in / api / user / login. rake routes list the following:
api_user_login POST /api/user/login(.:format) api/user/mobile/sessions
My specification has the following:
describe Mobile::SessionsController do
render_views
describe '#create' do
context 'for some condition' do
let(:params) do
{
}
end
before do
post :create, params.merge(format: :json)
end
it 'should render a json response' do
expect(response.headers['Content-Type']).to eq 'application/json; charset=utf-8'
end
...
When I run spec, it gives the following error:
AbstractController::ActionNotFound: Could not find devise mapping for path "/mobile/sessions/create.json?params=blah.
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]
devise_for (, skip:: all, devise_for , ), . , ( devise.mapping) , , . , , , . ?
!