跳至内容 跳至搜索

延迟加载钩子

LazyLoadHooks 允许 Rails 延迟加载许多组件,从而使应用程序启动速度更快。由于此功能,现在无需在启动时仅为了应用配置而需要 ActiveRecord::Base。相反,注册了一个钩子,该钩子在加载 ActiveRecord::Base 后应用配置。这里 ActiveRecord::Base 用作示例,但此功能也可以应用于其他地方。

以下是一个使用 on_load 方法注册钩子的示例。

initializer 'active_record.initialize_timezone' do
  ActiveSupport.on_load(:active_record) do
    self.time_zone_aware_attributes = true
    self.default_timezone = :utc
  end
end

ActiveRecord::Base 的全部内容已评估后,将调用 run_load_hooksActiveRecord::Base 的最后一行是

ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)

run_load_hooks 然后将执行所有使用 on_load 方法注册的钩子。在上面的示例中,它将执行 initializer 中的代码块。

注册已经运行的钩子会导致该钩子立即执行。这允许钩子嵌套,以用于依赖于多个延迟加载组件的代码。

initializer "action_text.renderer" do
  ActiveSupport.on_load(:action_controller_base) do
    ActiveSupport.on_load(:action_text_content) do
      self.default_renderer = Class.new(ActionController::Base).renderer
    end
  end
end
方法
O
R

实例公共方法

on_load(name, options = {}, &block)

声明一个代码块,该代码块将在 Rails 组件完全加载时执行。如果组件已经加载,则立即执行代码块。

选项

  • :yield - 将 run_load_hooks 的对象传递给 block

  • :run_once - 给定的 block 仅运行一次。

# File activesupport/lib/active_support/lazy_load_hooks.rb, line 60
def on_load(name, options = {}, &block)
  @loaded[name].each do |base|
    execute_hook(name, base, options, block)
  end

  @load_hooks[name] << [block, options]
end

run_load_hooks(name, base = Object)

执行所有通过 on_load 注册到 name 的代码块,使用 base 作为评估上下文。

ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)

在上面的示例中,它将执行在 ActiveRecord::Base 类中为 :active_record 注册的所有钩子。

# File activesupport/lib/active_support/lazy_load_hooks.rb, line 75
def run_load_hooks(name, base = Object)
  @loaded[name] << base
  @load_hooks[name].each do |hook, options|
    execute_hook(name, base, options, hook)
  end
end