Rails引擎内的控制器(宝石)

时间:2015-10-25 22:00:43

标签: ruby-on-rails devise rails-engines

我正在学习如何构建一个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经验的人可以解释一下吗?

2 个答案:

答案 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推荐时,它们不会发生冲突。

如果您有更具体的要求,我很乐意为您解答。