module IOPromise::DataLoader

Public Class Methods

included(base) click to toggle source
# File lib/iopromise/data_loader.rb, line 26
def self.included(base)
  base.extend(ClassMethods)
end

Public Instance Methods

async_attributes() click to toggle source
# File lib/iopromise/data_loader.rb, line 30
def async_attributes
  @async_attributes ||= Promise.all(attr_async_promises)
end
sync() click to toggle source
# File lib/iopromise/data_loader.rb, line 34
def sync
  async_attributes.sync
  self
end

Protected Instance Methods

attr_async_promises() click to toggle source
# File lib/iopromise/data_loader.rb, line 40
def attr_async_promises
  self.class.attr_async_names.flat_map do |k|
    p = send("async_#{k}")
    case p
    when ::IOPromise::DataLoader
      # greedily, recursively preload all nested data that we know about immediately
      p.attr_async_promises
    when ::Promise
      # allow nesting of dataloaders chained behind other promises
      resolved = p.then do |result|
        if result.is_a?(::IOPromise::DataLoader)
          # likewise, if we resolved a promise that we can recurse, load that data too.
          result.async_attributes
        else
          result
        end
      end

      [resolved]
    else
      raise TypeError.new("Instance variable #{k.to_s} used with attr_async but was not a promise or a IOPromise::DataLoader.")
    end
  end
end