我正在学习如何构建一个Rails gem(引擎,更具体)。我首先阅读了一些像Devise这样的现有开源代码,但我无法理解其中的控制器。在app/controllers
中,_devise_controller.rb_具有模块层次结构
class DeviseController < Devise.parent_controller.constantize
但在lib/devise/controllers/
中还有许多具有模块层次结构的控制器
module Devise
module Controllers
这些控制器之间有什么区别(当我得到“users / sign_up”时会调用它们)?有更多使用Devise经验的人可以解释一下吗?
答案 0 :(得分:1)
我假设Devise控制器位于自己的模块中,不会污染全局命名空间。检查例如this answer中新案例基于Devise的 RegistrationController
的案例class RegistrationsController < Devise::RegistrationsController
如果它不在 Devise 中,则名称 RegistrationsController 将被占用。
app/controllers/devise
下的控制器是路由器重定向请求的实际控制器。 lib/devise/controllers
下的那些是控制器的助手,因此为方便起见,它们在模块Devise :: Controllers中。
调用users/sign_up
时,会将其路由到_registrations_controller.rb:6_。这不是通过 routes.rb 以正常方式完成的,可能是因为Devise需要调整每个应用的网址,因为您不总是使用 users 作为路径。而是由devise/rails/routes.rb
完成,这是行
mount_devise_token_auth_for 'User', at: 'auth'
从实际应用程序 routes.rb 转到。
答案 1 :(得分:1)
我在gem I wrote some time back中包含了控制器。
使用命名空间的一个主要原因是因为你的整个gem应该受到单个模块的胁迫:
#lib/exception_handler.rb
module ExceptionHandler
#Exception Handler
class Exceptions < Rails::Engine
这意味着如果你从gem中调用控制器(这意味着是自包含的),你通常必须调用它里面模块:
ExceptionHandler::ExceptionController.action(:show).call(env) }
-
从Devise的意义上讲,将控制器包含在命名空间中是有道理的,原因有两个:
当我收到“users / sign_up”
时调用
设计控制器可以按routes Devise sets:
进行细分 new_user_session GET /users/sign_in {controller:"devise/sessions", action:"new"}
user_session POST /users/sign_in {controller:"devise/sessions", action:"create"}
destroy_user_session DELETE /users/sign_out {controller:"devise/sessions", action:"destroy"}
这些只是sessions
控制器(处理登录等)的路由。
还有其他路线,包括registrations
等。
这里的关键是要明白Devise必须“开箱即用” - 否则大多数人都不会使用它。它通过自包含其控制器来实现这一点,确保在sanfor
推荐时,它们不会发生冲突。
如果您有更具体的要求,我很乐意为您解答。