Module: ActiveSupport::LazyLoadHooks

Included in:
ActiveSupport
Defined in:
activesupport/lib/active_support/lazy_load_hooks.rb

Overview

LazyLoadHooks allows Rails to lazily load a lot of components and thus making the app boot faster. Because of this feature now there is no need to require ActiveRecord::Base at boot time purely to apply configuration. Instead a hook is registered that applies configuration once ActiveRecord::Base is loaded. Here ActiveRecord::Base is used as example but this feature can be applied elsewhere too.

Here is an example where on_load method is called to register a hook.

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

When the entirety of ActiveRecord::Base has been evaluated then run_load_hooks is invoked. The very last line of ActiveRecord::Base is:

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

run_load_hooks will then execute all the hooks that were registered with the on_load method. In the case of the above example, it will execute the block of code that is in the initializer.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object

:nodoc:


30
31
32
33
34
35
36
# File 'activesupport/lib/active_support/lazy_load_hooks.rb', line 30

def self.extended(base) # :nodoc:
  base.class_eval do
    @load_hooks = Hash.new { |h, k| h[k] = [] }
    @loaded     = Hash.new { |h, k| h[k] = [] }
    @run_once   = Hash.new { |h, k| h[k] = [] }
  end
end

Instance Method Details

#on_load(name, options = {}, &block) ⇒ Object

Declares a block that will be executed when a Rails component is fully loaded.

Options:

  • :yield - Yields the object that run_load_hooks to block.

  • :run_once - Given block will run only once.


45
46
47
48
49
50
51
# File 'activesupport/lib/active_support/lazy_load_hooks.rb', line 45

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) ⇒ Object

Executes all blocks registered to name via on_load, using base as the evaluation context.

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

In the case of the above example, it will execute all hooks registered for :active_record within the class ActiveRecord::Base.


60
61
62
63
64
65
# File 'activesupport/lib/active_support/lazy_load_hooks.rb', line 60

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