I\'m trying to split my rails project in a front-end for regular users and a back-end for admins. Therefore i have created a namespace \'admin\' so that i can easily control adm
Simply "moving" Devise to the admin namespace is wrong. Devise uses controllers like Devise::SessionsController
and that cannot be "moved".
I usually create my own controllers and inherit them from Devise:
class Admin::SessionsController < ::Devise::SessionsController
layout "admin"
# the rest is inherited, so it should work
end
And configure this in config/routes.rb
:
devise_for :admins, :controllers => { :sessions => "admin/sessions" }
Or you could change the layout only, by making the layout a bit more complex:
class ApplicationController < ActionController::Base
layout :layout
private
def layout
if devise_controller? && devise_mapping.name == :admin
"admin"
else
"application"
end
end
end
Both Jack Chu and iain solutions should solve the problem plus generating your views in order to customize the layout of the login form.
So in your config/routes.rb
you should have
scope '/subfolder' do
devise_for :admins, :controllers => { :sessions => "subfolder/sessions" }
end
namespace :subfolder do
match '/', :to => 'subcontroller#action'
end
Remember di create your own controllers for sessions as you are already doing.
Probably you will need to generate your views, too by using rails generate devise:views
Check this for any doubt on devise tasks.
If you want to put your devise views in views/admin/admins/ and your controllers in controllers/admin/admins/:
your sessions_controller.rb in controllers/admin/admins:
class Admin::Admins::SessionsController < ::Devise::SessionsController
layout "admin/connection"
end
routes.rb :
namespace :admin do |admin|
devise_for :admins, :controllers => { :sessions => "admin/admins/sessions" }
end
Generating devise views :
rails g devise:views admin/admins
How about specifying devise the path to take, place this outside your namespace.
devise_for :users, path: 'admins'
This will generate the following routes
new_user_session GET /admins/sign_in(.:format) devise/sessions#new
user_session POST /admins/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /admins/sign_out(.:format) devise/sessions#destroy
user_password POST /admins/password(.:format) passwords#create
new_user_password GET /admins/password/new(.:format) passwords#new
edit_user_password GET /admins/password/edit(.:format) passwords#edit
PUT /admins/password(.:format) passwords#update
cancel_user_registration GET /admins/cancel(.:format) registrations#cancel
user_registration POST /admins(.:format) registrations#create
new_user_registration GET /admins/sign_up(.:format) registrations#new
edit_user_registration GET /admins/edit(.:format) registrations#edit
PUT /admins(.:format) registrations#updat
DELETE /admins(.:format) registrations#destroy
You don't have to change anything in that case, if this is what you are looking for.
Happy Coding :)
In addition to the first solution of the answer of iain i had to generate views of devise or else it throws a template missing exception.
generate views with
rails g devise_views
The views will be located in views>devise. Move the created map 'sessions' to the map views>admin
How about just moving the devise_for
method into a scope:
scope '/admin' do
devise_for :admins
end
With namespace, the controllers will try to look for an Admin::SessionController
that wont exist. With scope it doesn't, so that should work.