Sha256: e7ce54d3e7914d0c5e2dd5f38a8f00f75a891711c0a9e8fe51e8e893d7864879

Contents?: true

Size: 1.92 KB

Versions: 12

Compression:

Stored size: 1.92 KB

Contents

# This object holds the preloaded data from the json response - essentially
#   the preloaded foreign keys
module JsonApiClient
  class LinkedData
    attr_reader :link_definition,
                :record_class

    extend Forwardable
    def_delegators :link_definition, :has_link?

    def initialize(data, link_definition, record_class)
      @link_definition = link_definition
      @record_class = record_class
      @results_by_type_by_id = {}

      data.each do |type, results|
        klass = klass_for(type)
        add_data(type, results.map{|result| klass.new(result)})
      end
    end

    def data_for(type, ids)
      ids = Array(ids)

      # the name of the linked data is provided by the link definition from the result
      attr_name = link_definition.attribute_name_for(type)

      # get any preloaded data from the result
      type_data = @results_by_type_by_id.fetch(attr_name, {})

      # find the associated class for the data
      klass = klass_for(type)

      # return all the found records
      found, missing = ids.partition { |id| type_data[id].present? }

      # make another api request if there are missing records
      fetch_data(klass, type, missing) if missing.present?

      # reload data
      type_data = @results_by_type_by_id.fetch(attr_name, {})

      ids.map do |id|
        type_data[id]
      end
    end

    # make an api request to fetch the missing data
    def fetch_data(klass, type, missing_ids)
      path = URI(link_definition.url_for(type, missing_ids)).path

      query = Query::Linked.new(path)
      results = klass.run_request(query)

      key = link_definition.attribute_name_for(type).to_s
      add_data(key, results)
    end

    def add_data(key, data)
      @results_by_type_by_id[key] ||= {}
      @results_by_type_by_id[key].merge!(data.index_by{|datum| datum["id"]})
    end

    def klass_for(type)
      Utils.compute_type(record_class, type.to_s.pluralize.classify)
    end

  end
end

Version data entries

12 entries across 12 versions & 1 rubygems

Version Path
json_api_client-0.9.4 lib/json_api_client/linked_data.rb
json_api_client-0.9.3 lib/json_api_client/linked_data.rb
json_api_client-0.9.2 lib/json_api_client/linked_data.rb
json_api_client-0.9.0 lib/json_api_client/linked_data.rb
json_api_client-0.8.1 lib/json_api_client/linked_data.rb
json_api_client-0.8.0 lib/json_api_client/linked_data.rb
json_api_client-0.7.1 lib/json_api_client/linked_data.rb
json_api_client-0.7.0 lib/json_api_client/linked_data.rb
json_api_client-0.6.0 lib/json_api_client/linked_data.rb
json_api_client-0.5.1 lib/json_api_client/linked_data.rb
json_api_client-0.5.0 lib/json_api_client/linked_data.rb
json_api_client-0.4.0 lib/json_api_client/linked_data.rb