class DHS::Record::Chainable::Chain

A sequence of links

Attributes

Public Class Methods

new(record_class, link, record = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 157
def initialize(record_class, link, record = nil)
  @record_class = record_class
  @record = record
  self._links = [link].compact
end
unfold(args) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 153
def self.unfold(args)
  (args.size == 1) ? args[0] : args
end

Public Instance Methods

all(hash = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 239
def all(hash = nil)
  push([Parameter.new(hash), Option.new(all: true)])
end
create(data = {}) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 163
def create(data = {})
  @record_class.create(data, resolved_options)
end
create!(data = {}) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 167
def create!(data = {})
  @record_class.create!(data, resolved_options)
end
destroy(options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 181
def destroy(options = nil)
  options ||= {}
  options = options.respond_to?(:to_h) ? options : { id: options }
  if @record
    @record.destroy(resolved_options.merge(options))
  else
    @record_class.destroy(options, resolved_options)
  end
end
expanded(options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 243
def expanded(options = nil)
  push(Option.new(expanded: options || true))
end
fetch() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 339
def fetch
  resolve
end
find(*args) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 290
def find(*args)
  @record_class.find(*args.push(resolved_options))
end
find_by(params = {}) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 294
def find_by(params = {})
  @record_class.find_by(params, resolved_options)
end
find_by!(params = {}) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 298
def find_by!(params = {})
  @record_class.find_by!(params, resolved_options)
end
first!() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 302
def first!
  @record_class.first!(resolved_options)
end
ignore(*error_classes) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 251
def ignore(*error_classes)
  chain = push(IgnoredError.new(error_classes.shift))
  error_classes.each do |error_class|
    chain._links.push(IgnoredError.new(error_class))
  end
  chain
end
include_all!(args) click to toggle source

Adds additional .references(name_of_linked_resource: { all: true }) to all linked resources included with includes_all

# File lib/dhs/concerns/record/chainable.rb, line 333
def include_all!(args)
  includes_all_to_references(args).each do |reference|
    _links.push(reference)
  end
end
includes(*args) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 280
def includes(*args)
  chain = push(Include.new(Chain.unfold(args)))
  chain.include_all!(args)
  chain
end
includes_first_page(*args) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 276
def includes_first_page(*args)
  push(Include.new(Chain.unfold(args)))
end
includes_values() click to toggle source

Returns a hash of include conditions

# File lib/dhs/concerns/record/chainable.rb, line 322
def includes_values
  chain_includes
end
limit(argument = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 267
def limit(argument = nil)
  return resolve.limit if argument.blank?
  push(Pagination.new(per: argument))
end
option_values_hash() click to toggle source

Returns a hash of options

# File lib/dhs/concerns/record/chainable.rb, line 312
def option_values_hash
  chain_options
end
options(hash = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 247
def options(hash = nil)
  push(Option.new(hash))
end
order(*args) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 225
def order(*args)
  order_params = {}
  args.each do |arg|
    if arg.is_a?(Hash)
      arg.each do |key, value|
        order_params[key] = value
      end
    else
      order_params[arg.to_s] = 'asc'
    end
  end
  push(Parameter.new(order: order_params))
end
page(page) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 259
def page(page)
  push(Pagination.new(page: page))
end
pagination_values_hash() click to toggle source

Returns a hash of pagination values

# File lib/dhs/concerns/record/chainable.rb, line 317
def pagination_values_hash
  chain_pagination
end
partial_update(data = {}, options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 201
def partial_update(data = {}, options = nil)
  options ||= {}
  @record.update(data, resolved_options.merge(options), true)
end
partial_update!(data = {}, options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 206
def partial_update!(data = {}, options = nil)
  options ||= {}
  @record.update!(data, resolved_options.merge(options), true)
end
per(per) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 263
def per(per)
  push(Pagination.new(per: per))
end
references(*args) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 286
def references(*args)
  push(Reference.new(Chain.unfold(args)))
end
references_values() click to toggle source

Returns a hash of reference options

# File lib/dhs/concerns/record/chainable.rb, line 327
def references_values
  chain_references
end
rescue(error_class, handler) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 272
def rescue(error_class, handler)
  push(ErrorHandling.new(error_class => handler))
end
save(options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 176
def save(options = nil)
  options ||= {}
  @record.save(resolved_options.merge(options))
end
save!(options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 171
def save!(options = nil)
  options ||= {}
  @record.save!(resolved_options.merge(options))
end
update(data = {}, options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 191
def update(data = {}, options = nil)
  options ||= {}
  @record.update(data, resolved_options.merge(options))
end
update!(data = {}, options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 196
def update!(data = {}, options = nil)
  options ||= {}
  @record.update!(data, resolved_options.merge(options))
end
valid?(options = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 211
def valid?(options = nil)
  options ||= {}
  @record.valid?(resolved_options.merge(options))
end
Also aliased as: validate
validate(options = nil)
Alias for: valid?
where(args = nil) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 217
def where(args = nil)
  if DHS::Record.href?(args)
    push(Option.new(url: args))
  else
    push(Parameter.new(args))
  end
end
where_values_hash() click to toggle source

Returns a hash of where conditions

# File lib/dhs/concerns/record/chainable.rb, line 307
def where_values_hash
  chain_parameters
end

Protected Instance Methods

method_missing(name, *args, **keyword_args, &block) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 345
def method_missing(name, *args, **keyword_args, &block)
  scope = @record_class.scopes[name]
  return instance_exec(*args, &scope) if scope
  resolve.send(name, *args, **keyword_args, &block)
end
resolve() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 356
def resolve
  return @resolved if defined?(@resolved)
  response_data = @record_class.request(resolved_options)
  @resolved = response_data ? @record_class.new(response_data) : nil
end
resolved_options() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 362
def resolved_options
  options = chain_options
  options = options.deep_merge(params: chain_parameters.merge(chain_pagination))
  options = options.merge(rescue: chain_error_handler) if chain_error_handler.present?
  options = options.merge(ignore: chain_ignored_errors) if chain_ignored_errors.present?
  options = options.merge(including: chain_includes) if chain_includes.present?
  options = options.merge(referencing: chain_references) if chain_references.present?
  options
end
respond_to_missing?(name, include_all = false) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 351
def respond_to_missing?(name, include_all = false)
  @record_class.scopes[name] ||
    resolve.respond_to?(name, include_all)
end

Private Instance Methods

chain_error_handler() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 424
def chain_error_handler
  @chain_error_handler ||= _links.select { |link| link.is_a? ErrorHandling }
end
chain_ignored_errors() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 428
def chain_ignored_errors
  @chain_ignored_errors ||= _links
    .select { |link| link.is_a? IgnoredError }
    .map { |link| link.data }
end
chain_includes() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 438
def chain_includes
  @chain_includes ||= DHS::Complex.reduce(
    _links
      .select { |link| link.is_a?(Include) && link.data.present? }
      .map { |link| link.data }
  )
end
chain_options() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 420
def chain_options
  @chain_options ||= merge_links(_links.select { |link| link.is_a? Option })
end
chain_pagination() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 434
def chain_pagination
  @chain_pagination ||= resolve_pagination(_links.select { |link| link.is_a? Pagination })
end
chain_parameters() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 416
def chain_parameters
  @chain_parameters ||= merge_links(_links.select { |link| link.is_a? Parameter })
end
chain_references() click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 446
def chain_references
  @chain_references ||= DHS::Complex.reduce(
    _links
      .select { |link| link.is_a?(Reference) && link.data.present? }
      .map { |link| link.data }
  )
end
includes_all_to_references(args, parent = nil) click to toggle source

Translates includes_all(resources:) to the internal datastructure references(resource: { all: true })

# File lib/dhs/concerns/record/chainable.rb, line 376
def includes_all_to_references(args, parent = nil)
  references = []
  if args.is_a?(Array)
    includes_all_to_references_for_arrays!(references, args, parent)
  elsif args.is_a?(Hash)
    includes_all_to_references_for_hash!(references, args, parent)
  elsif args.is_a?(Symbol)
    includes_all_to_references_for_symbol!(references, args, parent)
  end
  references
end
includes_all_to_references_for_arrays!(references, args, parent) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 388
def includes_all_to_references_for_arrays!(references, args, parent)
  args.each do |part|
    references.concat(includes_all_to_references(part, parent))
  end
end
includes_all_to_references_for_hash!(references, args, parent) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 394
def includes_all_to_references_for_hash!(references, args, parent)
  args.each do |key, value|
    parent ||= { all: true }
    references.concat([Reference.new(key => parent)])
    references.concat(includes_all_to_references(value, parent))
  end
end
includes_all_to_references_for_symbol!(references, args, parent) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 402
def includes_all_to_references_for_symbol!(references, args, parent)
  if parent.present?
    parent[args] = { all: true }
  else
    references.concat([Reference.new(args => { all: true })])
  end
end
push(link) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 410
def push(link)
  clone = self.clone
  clone._links = _links + [link].flatten.compact
  clone
end
resolve_pagination(links) click to toggle source
# File lib/dhs/concerns/record/chainable.rb, line 454
def resolve_pagination(links)
  return {} if links.empty?
  page = 1
  per = DHS::Pagination::Base::DEFAULT_LIMIT
  links.each do |link|
    page = link[:page] if link[:page].present?
    per = link[:per] if link[:per].present?
  end
  pagination = @record_class.pagination_class
  {
    @record_class.pagination_key(:parameter) => pagination.page_to_offset(page, per),
    @record_class.limit_key(:parameter) => per
  }
end