class JsonApiClient::Query::Builder

Attributes

klass[R]

Public Class Methods

new(klass, opts = {}) click to toggle source
# File lib/json_api_client/query/builder.rb, line 10
def initialize(klass, opts = {})
  @klass             = klass
  @primary_key       = opts.fetch( :primary_key, nil )
  @pagination_params = opts.fetch( :pagination_params, {} )
  @path_params       = opts.fetch( :path_params, {} )
  @additional_params = opts.fetch( :additional_params, {} )
  @filters           = opts.fetch( :filters, {} )
  @includes          = opts.fetch( :includes, [] )
  @orders            = opts.fetch( :orders, [] )
  @fields            = opts.fetch( :fields, [] )
end

Public Instance Methods

==(other) click to toggle source
# File lib/json_api_client/query/builder.rb, line 119
def ==(other)
  return false unless other.is_a?(self.class)

  hash == other.hash
end
Also aliased as: eql?
all()
Alias for: to_a
build(attrs = {}) click to toggle source
# File lib/json_api_client/query/builder.rb, line 69
def build(attrs = {})
  klass.new @path_params.merge(attrs.with_indifferent_access)
end
create(attrs = {}) click to toggle source
# File lib/json_api_client/query/builder.rb, line 73
def create(attrs = {})
  klass.create @path_params.merge(attrs.with_indifferent_access)
end
eql?(other)
Alias for: ==
find(args = {}) click to toggle source
# File lib/json_api_client/query/builder.rb, line 93
def find(args = {})
  if klass.raise_on_blank_find_param && args.blank?
    raise Errors::NotFound, nil, 'blank .find param'
  end

  case args
  when Hash
    scope = where(args)
  else
    scope = _new_scope( primary_key: args )
  end

  scope._fetch
end
first() click to toggle source
# File lib/json_api_client/query/builder.rb, line 61
def first
  paginate(page: 1, per_page: 1).to_a.first
end
hash() click to toggle source
# File lib/json_api_client/query/builder.rb, line 112
def hash
  [
    klass,
    params
  ].hash
end
includes(*tables) click to toggle source
# File lib/json_api_client/query/builder.rb, line 34
def includes(*tables)
  _new_scope( includes: parse_related_links(*tables) )
end
last() click to toggle source
# File lib/json_api_client/query/builder.rb, line 65
def last
  paginate(page: 1, per_page: 1).pages.last.to_a.last
end
method_missing(method_name, *args, &block) click to toggle source
# File lib/json_api_client/query/builder.rb, line 108
def method_missing(method_name, *args, &block)
  to_a.send(method_name, *args, &block)
end
order(*args) click to toggle source
# File lib/json_api_client/query/builder.rb, line 30
def order(*args)
  _new_scope( orders: parse_orders(*args) )
end
page(number) click to toggle source
# File lib/json_api_client/query/builder.rb, line 49
def page(number)
  _new_scope( pagination_params: { klass.paginator.page_param => number || 1 } )
end
paginate(conditions = {}) click to toggle source
# File lib/json_api_client/query/builder.rb, line 42
def paginate(conditions = {})
  scope = _new_scope
  scope = scope.page(conditions[:page]) if conditions[:page]
  scope = scope.per(conditions[:per_page]) if conditions[:per_page]
  scope
end
params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 77
def params
  filter_params
    .merge(pagination_params)
    .merge(includes_params)
    .merge(order_params)
    .merge(select_params)
    .merge(primary_key_params)
    .merge(path_params)
    .merge(additional_params)
end
per(size) click to toggle source
# File lib/json_api_client/query/builder.rb, line 53
def per(size)
  _new_scope( pagination_params: { klass.paginator.per_page_param => size } )
end
select(*fields) click to toggle source
# File lib/json_api_client/query/builder.rb, line 38
def select(*fields)
  _new_scope( fields: parse_fields(*fields) )
end
to_a() click to toggle source
# File lib/json_api_client/query/builder.rb, line 88
def to_a
  @to_a ||= _fetch
end
Also aliased as: all
where(conditions = {}) click to toggle source
# File lib/json_api_client/query/builder.rb, line 22
def where(conditions = {})
  # pull out any path params here
  path_conditions = conditions.slice(*klass.prefix_params)
  unpathed_conditions = conditions.except(*klass.prefix_params)

  _new_scope( path_params: path_conditions, filters: unpathed_conditions )
end
with_params(more_params) click to toggle source
# File lib/json_api_client/query/builder.rb, line 57
def with_params(more_params)
  _new_scope( additional_params: more_params )
end

Protected Instance Methods

_fetch() click to toggle source
# File lib/json_api_client/query/builder.rb, line 128
def _fetch
  klass.requestor.get(params)
end

Private Instance Methods

_new_scope( opts = {} ) click to toggle source
# File lib/json_api_client/query/builder.rb, line 134
def _new_scope( opts = {} )
  self.class.new( @klass,
       primary_key:       opts.fetch( :primary_key, @primary_key ),
       pagination_params: @pagination_params.merge( opts.fetch( :pagination_params, {} ) ),
       path_params:       @path_params.merge( opts.fetch( :path_params, {} ) ),
       additional_params: @additional_params.deep_merge( opts.fetch( :additional_params, {} ) ),
       filters:           @filters.merge( opts.fetch( :filters, {} ) ),
       includes:          @includes + opts.fetch( :includes, [] ),
       orders:            @orders + opts.fetch( :orders, [] ),
       fields:            @fields + opts.fetch( :fields, [] ) )
end
additional_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 150
def additional_params
  @additional_params
end
filter_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 176
def filter_params
  @filters.empty? ? {} : {filter: @filters}
end
includes_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 172
def includes_params
  @includes.empty? ? {} : {include: @includes.join(",")}
end
order_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 180
def order_params
  @orders.empty? ? {} : {sort: @orders.join(",")}
end
pagination_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 162
def pagination_params
  if klass.paginator.ancestors.include?(Paginating::Paginator)
    # Original Paginator inconsistently wraps pagination params here. Keeping
    # default behavior for now so as not to break backward compatibility.
    @pagination_params.empty? ? {} : {page: @pagination_params}
  else
    @pagination_params
  end
end
parse_fields(*fields) click to toggle source
# File lib/json_api_client/query/builder.rb, line 222
def parse_fields(*fields)
  fields = fields.split(',') if fields.is_a? String
  fields.map do |field|
    case field
    when Hash
      field.each do |k,v|
        field[k] = parse_fields(v)
      end
      field
    else
      Array(field).flatten.map { |i| i.to_s.split(",") }.flatten.map(&:strip)
    end
  end.flatten
end
parse_orders(*args) click to toggle source
# File lib/json_api_client/query/builder.rb, line 208
def parse_orders(*args)
  args.map do |arg|
    case arg
    when Hash
      arg.map do |k, v|
        operator = (v == :desc ? "-" : "")
        "#{operator}#{k}"
      end
    else
      "#{arg}"
    end
  end.flatten
end
path_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 146
def path_params
  @path_params.empty? ? {} : {path: @path_params}
end
primary_key_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 154
def primary_key_params
  return {} unless @primary_key

  @primary_key.is_a?(Array) ?
    {klass.primary_key.to_s.pluralize.to_sym => @primary_key.join(",")} :
    {klass.primary_key => @primary_key}
end
select_params() click to toggle source
# File lib/json_api_client/query/builder.rb, line 184
def select_params
  if @fields.empty?
    {}
  else
    field_result = Hash.new { |h,k| h[k] = [] }
    @fields.each do |field|
      if field.is_a? Hash
        field.each do |k,v|
          field_result[k.to_s] << v
          field_result[k.to_s] = field_result[k.to_s].flatten
        end
      else
        field_result[klass.table_name] << field
      end
    end
    field_result.each { |k,v| field_result[k] = v.join(',') }
    {fields: field_result}
  end
end