I'm writing an API and am trying to login with the API and am getting uninitialized constant SessionsController
error followed by the tip to "Try running rake routes for more information on available routes." when I try to go to the URL
http://localhost:3000/api/v1/login
as a POST
My routes show that the route and action exist as shown:
api_v1_users GET /api/v1/users(.:format) api/v1/users#index {:format=>"json"}
POST /api/v1/users(.:format) api/v1/users#create {:format=>"json"}
new_api_v1_user GET /api/v1/users/new(.:format) api/v1/users#new {:format=>"json"}
edit_api_v1_user GET /api/v1/users/:id/edit(.:format) api/v1/users#edit {:format=>"json"}
api_v1_user GET /api/v1/users/:id(.:format) api/v1/users#show {:format=>"json"}
PUT /api/v1/users/:id(.:format) api/v1/users#update {:format=>"json"}
DELETE /api/v1/users/:id(.:format) api/v1/users#destroy {:format=>"json"}
new_api_v1_user_session GET /api/v1/login(.:format) sessions#new {:format=>"json"}
api_v1_user_session POST /api/v1/login(.:format) sessions#create {:format=>"json"}
destroy_api_v1_user_session DELETE /api/v1/logout(.:format) sessions#destroy {:format=>"json"}
api_v1_user_omniauth_authorize GET|POST /auth/:provider(.:format) authentications#passthru {:provider=>/twitter|facebook/, :format=>"json"}
api_v1_user_omniauth_callback GET|POST /auth/:action/callback(.:format) authentications#(?-mix:twitter|facebook) {:format=>"json"}
api_v1_user_password POST /api/v1/password(.:format) api/v1/passwords#create {:format=>"json"}
new_api_v1_user_password GET /api/v1/password/new(.:format) api/v1/passwords#new {:format=>"json"}
edit_api_v1_user_password GET /api/v1/password/edit(.:format) api/v1/passwords#edit {:format=>"json"}
PUT /api/v1/password(.:format) api/v1/passwords#update {:format=>"json"}
cancel_api_v1_user_registration GET /api/v1/cancel(.:format) registrations#cancel {:format=>"json"}
api_v1_user_registration POST /api/v1(.:format) registrations#create {:format=>"json"}
new_api_v1_user_registration GET /api/v1/sign_up(.:format) registrations#new {:format=>"json"}
edit_api_v1_user_registration GET /api/v1/edit(.:format) registrations#edit {:format=>"json"}
PUT /api/v1(.:format) registrations#update {:format=>"json"}
DELETE /api/v1(.:format) registrations#destroy {:format=>"json"}
When I try to access the account using the authentication_token
url parameter, it works fine.
http://localhost:3000/api/v1/users/39?user_token=DxwspVzYSpsiLosd9xcE
Using that I can make PUT
and GET
requests no problem.
My routes look like this:
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :users
devise_for :users, :path => '', path_names: {sign_in: "login", sign_out: "logout"},
controllers: {omniauth_callbacks: "authentications", registrations: "registrations", sessions: "sessions"}
end
end
I assume it's a problem in my SessionsController, but can't figure out why the PUT
request would work, but the POST
wouldn't. Here is the SessionsController
:
module Api
module V1
class SessionsController < Devise::SessionsController
before_filter :authenticate_user!, except: [:create, :destroy]
before_filter :ensure_params_exist
skip_before_filter :verify_authenticity_token
def create
resource = User.find_for_database_authentication(email: params[:user_login][:email])
return invalid_login_attempt unless resource
if resource.valid_password?(params[:user_login][:password])
sign_in("user", resource)
resource.ensure_authentication_token!
render 'api/v1/sessions/new.json.jbuilder', status: 201
return
end
invalid_login_attempt
end
def destroy
current_user.reset_authentication_token
render json: {success: true}
end
protected
def ensure_params_exist
return unless params[:user_login].blank?
render json: {success: false, message: "missing user_login parameter"}, status: 422
end
def invalid_login_attempt
render 'api/v1/sessions/invalid.json.jbuilder', status: 401
end
end
end
end
So in my routes file I had
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :users
devise_for :users, path: '', path_names: {sign_in: "login", sign_out: "logout"},
controllers: {omniauth_callbacks: "authentications", registrations: "registrations", sessions: "sessions"}
end
end
I removed sessions: "sessions"
and everything works great. I'm not going to mark this as the correct answer because I don't know why this fixed the problem, or more specifically, why adding sessions: "sessions"
was causing the error in the first place. Hopefully someone can explain this for future readers.
EDIT:
I realized much later that the problem was that I was referencing the sessions_controller
, when I wanted to reference the api/v1/sessoins_controller
There is no regular sessions_controller
I just use the Devise one, but there is a sessions_controller
in the API/V1
namespace. So that is why the problem was happening.
For future reference for anyone else who comes across this problem, the error is telling you the controller you're looking for doesn't exist as it should, so to troubleshoot, make sure you are looking for the controller in the correct place, and with the correct name.