在命名空间中使用Devise

39
我正在尝试将我的Rails项目分为普通用户的前端和管理员的后端。因此,我创建了一个名为“admin”的命名空间,以便可以在地图管理员中轻松控制管理员特定的控制器方法/布局/身份验证。
我正在使用Devise仅注册/认证我的管理员。因为它仅用于管理员,所以我正在尝试将Devise移动到admin命名空间中。
我在routes.rb中尝试了以下内容,但在Devise的文档中没有找到确切的内容:
namespace 'admin'do 
  devise_for :admins
end

我还尝试过创建一个自定义的Devise::Sessions控制器,但似乎也行不通。

有人知道该怎么做吗?我应该只是使用自定义(管理员)布局的常规devise路由吗?

6个回答

44

将Devise简单地“移动”到admin命名空间是错误的。Devise使用像Devise :: SessionsController 这样的控制器,这不能被“移动”。

我通常会创建自己的控制器并从Devise继承:

class Admin::SessionsController < ::Devise::SessionsController
  layout "admin"
  # the rest is inherited, so it should work
end

并在config/routes.rb中进行配置:

devise_for :admins, :controllers => { :sessions => "admin/sessions" }

或者你可以仅仅改变布局,通过使布局变得更加复杂:

class ApplicationController < ActionController::Base

  layout :layout

  private

  def layout
    if devise_controller? && devise_mapping.name == :admin
      "admin"
    else
      "application"
    end
  end

end

非常感谢您易于理解的解决方案。我正在学习如何使用命名空间,所以您的第一个解决方案对我非常有帮助。 - Harm de Wit
为了设置自己的布局,没有必要继承每个设备控制器。您可以在application.rb中完成此操作。https://dev59.com/IGgu5IYBdhLWcg3wxZ3d#11085724 - secador de pelo

29

devise_for方法移动到作用域中如何:

scope '/admin' do
  devise_for :admins
end

使用命名空间,控制器将尝试查找一个不存在的Admin::SessionController。使用作用域不会这样,所以应该可以工作。


1
正是我想要的,干杯! - Michael De Silva
只想在此处添加到 Rails 路由中添加作用域的各种方式的文档链接 here - Vic

15

如何指定设备路径,请将其放在命名空间之外。

devise_for :users, path: 'admins'

这将生成以下路由

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

如果这正是您所寻找的,那么在这种情况下您不需要做任何更改。

愉快的编码 :)


5

无论是Jack Chu还是iain的解决方案都可以解决这个问题,并生成您的视图以自定义登录表单的布局。

因此,在您的config/routes.rb文件中,您应该有:

scope '/subfolder' do
   devise_for :admins, :controllers => { :sessions => "subfolder/sessions" }
end

namespace :subfolder do
  match '/', :to => 'subcontroller#action'
end

记得像你已经在做的那样为会话创建自己的控制器。可能你还需要使用“rails generate devise:views”生成视图。
点击这里查看关于devise任务的任何疑问。

1
如果您想将设备视图放在views/admin/admins/中,控制器放在controllers/admin/admins/中:
sessions_controller.rb应该放在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

生成 devise 视图:
rails g devise:views admin/admins

0
除了iain的第一个答案解决方案外,我还必须生成devise的视图,否则它会抛出模板丢失异常。
使用以下命令生成视图:
rails g devise_views

视图将位于 views>devise。将创建的 map 'sessions' 移动到地图 views>admin


1
实际上是 rails generate devise:views - Calavera
在旧版本中,它曾经是 devise_views。 :) - Matt Huggins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接