Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Devise with multiple namespaces for the same Model

I want to use Devise with two namespaces: an API namespace, and the default namespace, but the two seem to be conflicting when a user tries to sign in. Meaning, whichever namespace that references Devise first ends up being the final redirection place. Ex: If I try to create a new session under the default namespace it will fail on that user session path, and then attempt to create the session on the API/v1 sessions path.

How do I make the two act independently?

They are both referencing a User object. The user_sessions controller for the default namespace is 'user_sessions'. The user_sessions controller for the API/V1 namespace is '/api/v1/user_sessions'

    ---- ROUTES.RB -------
    MySite::Application.routes.draw do
    namespace :api do
   namespace :v1 do
     devise_for :users,:controllers => { :sessions => "api/v1/
user_sessions",:registrations=>"users" }
     ......
   end
 end
 devise_for :users,:controllers => { :sessions =>"user_sessions",:registrations=>"users" } do
    post 'users/sign_in' => 'user_sessions#create', :as => :user_session
    get 'users/sign_in' => 'user_sessions#new', :as => :new_user_session
    get 'users/sign_up' => 'user_sessions#new', :as => :new_user_session
    match 'users/sign_out' => 'user_sessions#destroy', :as => :destroy_user_session
    <.....>
 end

----- DEFAULT NAMESPACE USER_SESSIONS_CONTROLLER -----

class UserSessionsController < Devise::SessionsController
....
end
---- 

API NAMESPACE USER_SESSIONS_CONTROLLER ---- (this goes to my custom Devise base controller marked below)

class Api::V1::UserSessionsController < Api::V1::DeviseBaseController
...
end

---- API NAMESPACE CUSTOM DEVISE BASE CONTROLLER ----

class Api::V1::DeviseBaseController < Devise::SessionsController
       respond_to :json
end
like image 496
beeudoublez Avatar asked Apr 23 '12 17:04

beeudoublez


2 Answers

I found out that this isn't possible with Devise, you have to have one sign-in/sign out source.

Clean solution: Create routes for both your API and Web namespaces that point back to the same Devise controller code (say, /user/sessions). In there, call partials for the appropriate response (JSON, HTML). Those partials can sit in the view directories for each namespace, keeping things clean.

like image 114
beeudoublez Avatar answered Jan 02 '23 06:01

beeudoublez


You should need to define two diffrent roles for user like admin and end user.

and then define these routes for him

 FourtySixLabs::Application.routes.draw do

    namespace :admin do
     resources :posts
    end

    namespace :end_user do
      resources :posts
    end


  devise_for :users, :controllers => {
    :sessions => "users/sessions",
    :confirmation => "users/confirmations",
    :passwords => "users/passwords",
    :registrations => "users/registrations",
  }


  devise_for :users, as: :user do
    get 'admin', :to => 'users/sessions#new', :as => :new_user_session
    get "end_user", :to => "users/sessions#new"
    get "sign_out", :to => "users/sessions#destroy"
  end

 end

And then admin will login from this url localhost:3000/admin

And then end_user will login from this url localhost:3000/end_user

For defining roles see this

Rails : Adding an admin role using devise who can see all the users

Hope you will get idea

like image 41
Kashiftufail Avatar answered Jan 02 '23 06:01

Kashiftufail