为什么可以在不包含任何模块的情况下使用 current_user、authenticate_user! 等辅助方法的原因

The reason why it's possible to use helper method like current_user, authenticate_user!, and so on without including any module

标题是我的问题

devise为我们提供了许多有用的方法,如current_userauthenticate_user!等。我想知道为什么可以在不包含如下任何模块的情况下使用它们。

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
end

那些方法的定义是here

谁能帮帮我!

rails 的一大优点是您可以免费获得很多开箱即用的东西。顶层的其中一项是自动加载。

所以在 Devise 的情况下。当您安装 Devise 和 运行 generate 命令时,您会在 config/initializers/ 文件夹中获得一个 devise.rb 文件。该文件总是由 rails 在服务器启动和重新加载时自动加载。这就是所有这些方法能够在不导入任何东西的情况下使用这些设计方法的方式。

rails docs

阅读更多内容

答案是devise included its helper methods into ActionController代表你当Railson_load

# devise/rails.rb
module Devise
  class Engine < ::Rails::Engine
    # ...
    initializer "devise.url_helpers" do
      Devise.include_helpers(Devise::Controllers)
    end
    # ...
end

# devise.rb
  # ...
  def self.include_helpers(scope)
    ActiveSupport.on_load(:action_controller) do
      include scope::Helpers if defined?(scope::Helpers)
      include scope::UrlHelpers
    end

    ActiveSupport.on_load(:action_view) do
      include scope::UrlHelpers
    end
  end
  # ...   

我看到许多 3rd gem 使用 on_load 将他们的方法(或他们自己)包含到 Rails 核心中,也许这是一种典型的方法(允许 Rails 延迟加载很多组件,从而使应用程序启动更快)。如果你安装了一些 gems 并且你可以在你的 model/controller/view 上使用它们的方法,那么这些 gems 会做同样的事情 devise 上面做的。

关于那些方法 current_userauthenticate_user! ...当它 include scope::Helpers 变成 Rails 时它们是 dynamic methods devise will generate(参见上面的代码和 link).