Class: BlueprinterActiveRecord::Preloader

Inherits:
Blueprinter::Extension
  • Object
show all
Includes:
Helpers
Defined in:
lib/blueprinter-activerecord/preloader.rb

Overview

A Blueprinter extension to automatically preload a Blueprint view’s ActiveRecord associations during render

Constant Summary collapse

DEFAULT_MAX_RECURSION =
10

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#count_preloads, #diff_preloads, #extract_preloads, #merge_values

Constructor Details

#initialize(auto: false, use: :preload) {|Object, Class, Symbol, Hash| ... } ⇒ Preloader

Initialize and configure the extension.

Parameters:

  • auto (true|false) (defaults to: false)

    When true, preload for EVERY ActiveRecord::Relation passed to a Blueprint

  • use (:preload|:includes) (defaults to: :preload)

    When ‘auto` is true, use this method (e.g. :preload) for preloading

Yields:

  • (Object, Class, Symbol, Hash)

    Instead of passing ‘auto` as a boolean, you may define a block that accepts the object to render, the blueprint class, the view, and options. If the block returns true, auto preloading will take place.



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/blueprinter-activerecord/preloader.rb', line 18

def initialize(auto: false, use: :preload, &auto_proc)
  @auto = auto
  @auto_proc = auto_proc
  @use =
    case use
    when :preload, :includes
      use
    else
      raise ArgumentError, "Unknown value '#{use.inspect}' for `BlueprinterActiveRecord::Preloader` argument 'use'. Valid values are :preload, :includes."
    end
end

Instance Attribute Details

#autoObject (readonly)

Returns the value of attribute auto.



9
10
11
# File 'lib/blueprinter-activerecord/preloader.rb', line 9

def auto
  @auto
end

#auto_procObject (readonly)

Returns the value of attribute auto_proc.



9
10
11
# File 'lib/blueprinter-activerecord/preloader.rb', line 9

def auto_proc
  @auto_proc
end

#useObject (readonly)

Returns the value of attribute use.



9
10
11
# File 'lib/blueprinter-activerecord/preloader.rb', line 9

def use
  @use
end

Instance Method Details

#pre_render(object, blueprint, view, options) ⇒ Object

Implements the “pre_render” Blueprinter Extension to preload associations from a view. If auto is true, all ActiveRecord::Relation and ActiveRecord::AssociationRelation objects will be preloaded. If auto is false, only queries that have called ‘.preload_blueprint` will be preloaded.

NOTE: If auto is on, *don’t* be concerned that you’ll end up with duplicate preloads. Even if the query ends up with overlapping members in ‘preload’ and ‘includes’, ActiveRecord intelligently handles them. There are several unit tests which confirm this behavior.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/blueprinter-activerecord/preloader.rb', line 40

def pre_render(object, blueprint, view, options)
  if object.is_a?(ActiveRecord::Relation) && !object.loaded?
    if object.preload_blueprint_method || auto || auto_proc&.call(object, blueprint, view, options) == true
      object.before_preload_blueprint = extract_preloads object
      blueprint_preloads = self.class.preloads(blueprint, view, model: object.model)
      loader = object.preload_blueprint_method || use
      object.public_send(loader, blueprint_preloads)
    else
      object
    end
  else
    object
  end
end