lib/heartland/client/collection.rb
module HeartlandRetail
class Client
##
# Mixin provides {Resource} with special methods for convenient interaction
# with collection resources.
module Collection
include ::Enumerable
##
# Iterates over all results from the collection and yields each one to
# the block, fetching pages as needed.
#
# @raise [RequestFailed]
def each(&block)
call_client(:each, &block)
end
##
# Iterates over each page of results and yields the page to the block,
# fetching as needed.
#
# @raise [RequestFailed]
def each_page(&block)
call_client(:each_page, &block)
end
##
# Performs a request and returns the number of resources in the collection.
#
# @raise [RequestFailed]
#
# @return [Integer] The subordinate resource count
def count
call_client(:count)
end
##
# Returns true if count is greater than zero, else false.
#
# @see #count
#
# @raise [RequestFailed]
#
# @return [Boolean]
def empty?
count <= 0
end
##
# Returns a new resource with the given filters added to the query string.
#
# @see https://github.com/springboard/springboard-retail/blob/master/api/doc/filtering.md Heartland Retail collection API filtering docs
#
# @param [String, Hash] new_filters Hash or JSON string of new filters
#
# @return [Resource]
def filter(new_filters)
new_filters = JSON.parse(new_filters) if new_filters.is_a?(String)
if filters = query['_filter']
filters = JSON.parse(filters)
filters = [filters] unless filters.is_a?(Array)
filters.push(new_filters)
else
filters = new_filters
end
query('_filter' => filters.to_json)
end
##
# Returns a new resource with the given sorts added to the query string.
#
# @example
# resource.sort('id,desc', 'name', 'custom@category,desc', :description)
#
# @param [#to_s] sorts One or more sort strings
#
# @return [Resource]
def sort(*sorts)
query('sort' => sorts)
end
##
# Returns a new resource with the given fields added to the query string as _only parameters.
#
# @example
# resource.only('id', :public_id)
#
# @param [#to_s] returns One or more fields
#
# @return [Resource]
def only(*fields)
query('_only' => fields)
end
##
# Performs a request to get the first result of the first page of the
# collection and returns it.
#
# @raise [RequestFailed]
#
# @return [Body] The first entry in the response :results array
def first
response = query(:per_page => 1, :page => 1).get!
response[:results].first
end
##
# Performs repeated GET requests to the resource and yields results to
# the given block as long as the response includes more results.
#
# @raise [RequestFailed]
def while_results(&block)
loop do
results = get![:results]
break if results.nil? || results.empty?
results.each(&block)
end
end
end
end
end