I am working on an existing web application that uses Rails 3 and Devise. My task at the moment is to add a JSON API to the application. I have created a Mobile::SessionsController (< Devise::SessionsController) that implements '#create' with a data-only response.
The issue is in the routing. Right now, the relevant parts of routes.rb are as follows:
# For the web app:
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
# And for the API, later on:
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 at /api/user/login. rake routes lists the following:
api_user_login POST /api/user/login(.:format) api/user/mobile/sessions#create
In my spec, there's the following:
describe Mobile::SessionsController do
render_views
describe '#create' do
context 'for some condition' do
let(:params) do
{
# basic params
}
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 the 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]
I've tried many different configurations within the second devise_for block (modules, whether or not to use skip: :all, removing the second devise_for entirely, putting it at different levels of the namespace) and I can't shake this error. My guess is that the second option there (the devise.mapping bit) is not the solution as it seems like it's not supposed to be bypassing the router at all. And since I have the route in precisely the sort of block it suggests for the first option, I'm befuddled as to how to fix this thing. How can I get this thing working?
Appreciate the help!
Aucun commentaire:
Enregistrer un commentaire