Skip to content

Commit

Permalink
Expand included links (#400)
Browse files Browse the repository at this point in the history
* finish bug fix and spec

* fix

* without extending data

* do not return an internal collection

* fix extend with references naming

* fix rubocop

* fix include issue

* patch version

* fix specs

* wrong variable

* request as before

* extend as before

* request spec as before

* adding spec to prevent internal collection from returning to the outside

* proper extension before continue including

* not for now

* fix rubocop
  • Loading branch information
spape authored Nov 20, 2020
1 parent 1ce78cb commit 4d33ada
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 18 deletions.
2 changes: 1 addition & 1 deletion lib/lhs/concerns/collection/internal_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def each(&_block)
def compact
dup.tap do |collection|
collection.compact! if collection.raw.present?
end
end.as_json # do not return an internal collection!
end

def compact!
Expand Down
32 changes: 18 additions & 14 deletions lib/lhs/concerns/data/extend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ module Extend

# Extends already fetched data (self) with additionally
# fetched data (addition) using the given key
def extend!(addition, key)
def extend!(addition, key = nil)
addition = cast_relation_class_for_extension(addition, key)
if collection?
extend_collection!(addition, key)
elsif self[key]._raw.is_a? Array
elsif _raw.is_a?(Array) || self[key]._raw.is_a?(Array)
extend_array!(addition, key)
elsif item?
extend_item!(addition, key)
Expand All @@ -22,14 +22,14 @@ def extend!(addition, key)

private

def cast_relation_class_for_extension(addition, key)
return addition if _record.nil? || _record._relations.nil? || _record._relations[key].nil?
def cast_relation_class_for_extension(addition, key = nil)
return addition if _record.nil? || key.nil? || _record._relations.nil? || _record._relations[key].nil?
addition.becomes(_record._relations[key][:record_class_name].constantize, errors: addition.errors, warnings: addition.warnings)
end

def extend_collection!(addition, key)
def extend_collection!(addition, key = nil)
map do |item|
item_raw = item._raw[key]
item_raw = key ? item._raw[key] : item._raw
item_raw.blank? ? [nil] : item_raw
end
.flatten
Expand All @@ -45,25 +45,25 @@ def extend_collection!(addition, key)
end
end

def extend_array!(addition, key)
self[key].zip(addition) do |item, additional_item|
def extend_array!(addition, key = nil)
(key ? self[key] : self).zip(addition) do |item, additional_item|
item._raw.merge!(additional_item._raw) if additional_item.present?
end
end

def extend_item!(addition, key)
def extend_item!(addition, key = nil)
return if addition.nil?
if addition.collection?
extend_item_with_collection!(addition, key)
else # simple case merges hash into hash
_raw[key.to_sym].merge!(addition._raw)
(key ? _raw[key.to_sym] : _raw).merge!(addition._raw)
end
end

def extend_item_with_collection!(addition, key)
target = self[key]
def extend_item_with_collection!(addition, key = nil)
target = (key ? self[key] : self)
if target._raw.is_a? Array
self[key] = addition.map(&:_raw)
self[key] = addition.map(&:_raw) if key
else # hash with items
extend_item_with_hash_containing_items!(target, addition)
end
Expand All @@ -72,7 +72,11 @@ def extend_item_with_collection!(addition, key)
def extend_item_with_hash_containing_items!(target, addition)
LHS::Collection.nest(input: target._raw, value: [], record: self) # inits the nested collection
if LHS::Collection.access(input: target._raw, record: self).empty?
LHS::Collection.nest(input: target._raw, value: addition.reject { |item| item.nil? }, record: self)
LHS::Collection.nest(
input: target._raw,
value: addition.reject { |item| item.nil? },
record: self
)
else
LHS::Collection.access(input: target._raw, record: self).each_with_index do |item, index|
item.merge!(addition[index])
Expand Down
15 changes: 13 additions & 2 deletions lib/lhs/concerns/record/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -321,11 +321,22 @@ def load_include_simple!(options, record)
end

# Continues loading included resources after one complete batch/level has been fetched
def continue_including(data, including, referencing)
handle_includes(including, data, referencing) if including.present? && data.present?
def continue_including(data, included, reference)
return data if included.blank? || data.blank?
expand_data!(data, included, reference) unless expanded_data?(data)
handle_includes(included, data, reference)
data
end

def expand_data!(data, _included, reference)
options = options_for_data(data)
options = extend_with_reference(options, reference)
record = record_for_options(options) || self
options = convert_options_to_endpoints(options) if record_for_options(options)
expanded_data = record.request(options)
data.extend!(expanded_data)
end

# Loads all included/linked resources,
# paginates itself to ensure all records are fetched
def load_all_included!(record, options)
Expand Down
2 changes: 1 addition & 1 deletion lib/lhs/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module LHS
VERSION = '25.0.3'
VERSION = '25.0.4'
end
5 changes: 5 additions & 0 deletions spec/record/compact_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ class User < LHS::Record
end

context '.compact' do

it 'does NOT return an internal data type, but the Record class' do
expect(places.compact.class).to eq User
end

it 'removes linked resouces which could not get fetched' do
expect(places.compact.length).to eq 1
expect(places.length).not_to eq 1 # leaves the original intact
Expand Down
72 changes: 72 additions & 0 deletions spec/record/includes_after_expansion_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true

require 'rails_helper'

describe LHS::Record do
context 'includes records after expansion' do

before do
class User < LHS::Record
endpoint 'http://users/{id}'
end

class Places < LHS::Record
endpoint 'http://users/{id}/places'
endpoint 'http://places/{id}'
end

class Contracts < LHS::Record
endpoint 'http://places/{place_id}/contracts'
end

stub_request(:get, 'http://users/1')
.to_return(
body: {
places: {
href: 'http://users/1/places'
}
}.to_json
)

stub_request(:get, 'http://users/1/places?limit=100')
.to_return(
body: {
items: [
{ href: 'http://places/345' }
],
total: 1,
offset: 0,
limit: 10
}.to_json
)

stub_request(:get, 'http://places/345')
.to_return(
body: {
contracts: {
href: "http://places/345/contracts?offset=0&limit=10"
}
}.to_json
)

stub_request(:get, 'http://places/345/contracts?offset=0&limit=10')
.to_return(
body: {
items: [
{
product: { name: 'OPL' }
}
]
}.to_json
)

end

it 'includes resources after expanding plain links' do
user = User.includes(places: :contracts).find(1)
expect(
user.places.first.contracts.first.product.name
).to eq 'OPL'
end
end
end

0 comments on commit 4d33ada

Please sign in to comment.