lhs 15.4.1 → 15.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: aae793d07885f60a78b3ba1a00620126cb5abe0e
4
- data.tar.gz: 3aae37c869254994499545d59b3059c0baac6038
2
+ SHA256:
3
+ metadata.gz: 9b17b15e82a095cf72eb05a914ced03c99f32d9c209b4a4e1c4e11c981a85f4c
4
+ data.tar.gz: 9f0303112e9847a8797582894c7d109eb19aba94144bd6c692b4ce9a3f06ee83
5
5
  SHA512:
6
- metadata.gz: b32efb89e71c58078da3c14a9e86ed094ead7a7553241944a7110ba62a9aaf24a18b248e9a511bca437464186f554689c211205c7aea97d6bc17318914192208
7
- data.tar.gz: 24b40b24d88d3047760687ec664430588c9abe84e70aa7268852ff51c99e917a95023a20b4958615f0a006551d98b8f1683b14d7f8cacafa1275090ae6264204
6
+ metadata.gz: 30f6194e142c4e83414f7e7c8d425f4297c92be6043518d310cf763c7a990546835d5ef604390987daf1b41ad19f054be7b3d11078c76212fc6a842d0d0742d3
7
+ data.tar.gz: 7306ff1a0d92ba35ea3992f3f5900d5bb6a90897918e8091006e174df90ab68c0261b885f27cc77795fd3b0a4cd5f180d43de35e361a998e84734ca5a5c0ecdc
data/README.md CHANGED
@@ -268,6 +268,28 @@ If no record is found, `nil` is returned.
268
268
 
269
269
  `first!` raises LHC::NotFound if nothing was found.
270
270
 
271
+ `first` can also be used with options:
272
+
273
+ ```ruby
274
+ Record.first(params: { color: :blue })
275
+ ```
276
+
277
+ `last` is an alias for finding the last record without parameters.
278
+
279
+ ```ruby
280
+ Record.last
281
+ ```
282
+
283
+ If no record is found, `nil` is returned.
284
+
285
+ `last!` raises LHC::NotFound if nothing was found.
286
+
287
+ `last` can also be used with options:
288
+
289
+ ```ruby
290
+ Record.last(params: { color: :blue })
291
+ ```
292
+
271
293
  # Find multiple single records in parallel
272
294
 
273
295
  In case you want to fetch multiple records by id in parallel, you can also do this with `find`:
@@ -27,9 +27,11 @@ class LHS::Collection < LHS::Proxy
27
27
  end
28
28
 
29
29
  def _collection
30
- raw = _data._raw if _data._raw.is_a?(Array)
31
- raw ||= _data.access(input: _data._raw, record: _record)
32
- Collection.new(raw, _data, _record)
30
+ @_collection ||= begin
31
+ raw = _data._raw if _data._raw.is_a?(Array)
32
+ raw ||= _data.access(input: _data._raw, record: _record)
33
+ Collection.new(raw, _data, _record)
34
+ end
33
35
  end
34
36
 
35
37
  def collection?
@@ -54,6 +56,7 @@ class LHS::Collection < LHS::Proxy
54
56
  if _collection.respond_to?(name)
55
57
  value = _collection.send(name, *args, &block)
56
58
  record = LHS::Record.for_url(value[:href]) if value.is_a?(Hash) && value[:href]
59
+ record ||= _record
57
60
  value = enclose_item_in_data(value) if value.is_a?(Hash)
58
61
  return value if METHOD_NAMES_EXLCUDED_FROM_WRAPPING.include?(name.to_s)
59
62
  wrap_return(value, record, name, args)
@@ -72,7 +75,7 @@ class LHS::Collection < LHS::Proxy
72
75
  # Encloses accessed collection item
73
76
  # by wrapping it in an LHS::Item
74
77
  def enclose_item_in_data(value)
75
- data = LHS::Data.new(value, _data)
78
+ data = LHS::Data.new(value, _data, _record)
76
79
  item = LHS::Item.new(data)
77
80
  LHS::Data.new(item, _data)
78
81
  end
@@ -11,7 +11,7 @@ class LHS::Collection < LHS::Proxy
11
11
  include Enumerable
12
12
 
13
13
  attr_accessor :raw
14
- delegate :length, :size, :last, :sample, :[], :present?, :blank?, :empty?,
14
+ delegate :length, :size, :first, :last, :sample, :[], :present?, :blank?, :empty?,
15
15
  :<<, :push, :compact, to: :raw
16
16
 
17
17
  def initialize(raw, parent, record)
@@ -6,6 +6,7 @@ class LHS::Data
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  def becomes(klass)
9
+ return self if self.class == klass && !is_a?(LHS::Data)
9
10
  klass.new(LHS::Data.new(_raw, _parent, klass))
10
11
  end
11
12
  end
@@ -73,10 +73,10 @@ class LHS::Proxy
73
73
  def wrap_return(value, record, name, args = nil)
74
74
  name = args.first if name == :[]
75
75
  return value unless worth_wrapping?(value)
76
- data = (value.is_a?(LHS::Data) || value.is_a?(LHS::Record)) ? value : LHS::Data.new(value, _data)
76
+ data = (value.is_a?(LHS::Data) || value.is_a?(LHS::Record)) ? value : LHS::Data.new(value, _data, _record, _request)
77
77
  data.errors = LHS::Problems::Nested::Errors.new(errors, name) if errors.any?
78
78
  data.warnings = LHS::Problems::Nested::Warnings.new(warnings, name) if warnings.any?
79
- return record.new(data) if record && !value.is_a?(LHS::Record)
79
+ return data.becomes(record) if record && !value.is_a?(LHS::Record)
80
80
  return data.becomes(_record._relations[name][:record_class_name].constantize) if _record && _record._relations[name]
81
81
  data
82
82
  end
@@ -0,0 +1,24 @@
1
+ require 'active_support'
2
+
3
+ class LHS::Record
4
+
5
+ module Last
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ def last(options = nil)
10
+ first_batch = find_by({}, options).parent
11
+ if first_batch.paginated?
12
+ pagination = first_batch._pagination
13
+ find_by({ pagination_key => pagination.class.page_to_offset(pagination.last_page, pagination.limit) }, options)
14
+ else
15
+ first_batch.last
16
+ end
17
+ end
18
+
19
+ def last!(options = nil)
20
+ find_by!({}, options)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -7,6 +7,10 @@ class LHS::Record
7
7
  # Kaminari-Interface
8
8
  delegate :current_page, :first_page, :last_page, :prev_page, :next_page, :limit_value, :total_pages, to: :_pagination
9
9
 
10
+ def paginated?(raw = nil)
11
+ self.class.paginated?(raw || _raw)
12
+ end
13
+
10
14
  def _pagination
11
15
  self.class.pagination(_data)
12
16
  end
@@ -26,6 +30,11 @@ class LHS::Record
26
30
  def pagination(data)
27
31
  pagination_class.new(data)
28
32
  end
33
+
34
+ # Checks if given raw is paginated or not
35
+ def paginated?(raw)
36
+ !!(raw.is_a?(Hash) && raw.dig(*total_key))
37
+ end
29
38
  end
30
39
  end
31
40
  end
@@ -282,16 +282,22 @@ class LHS::Record
282
282
  end
283
283
 
284
284
  def load_and_merge_set_of_paginated_collections!(data, options)
285
- options_for_this_batch = []
285
+ options_for_next_batch = []
286
286
  options.each_with_index do |element, index|
287
287
  next if element.nil?
288
288
  record = data[index]._record
289
289
  pagination = record.pagination(data[index])
290
290
  next if pagination.pages_left.zero?
291
- options_for_this_batch.push(options_for_next_batch(record, pagination, options[index], data[index]))
291
+ options_for_next_batch.push(
292
+ options_for_next_batch(record, pagination, options[index]).tap do |options|
293
+ options.each do |option|
294
+ option[:merge_with_index] = index
295
+ end
296
+ end
297
+ )
292
298
  end
293
- data._record.request(options_for_this_batch.flatten).each do |batch_data|
294
- merge_batch_data_with_parent!(batch_data, batch_data._request.options[:parent_data])
299
+ data._record.request(options_for_next_batch.flatten).each do |batch_data|
300
+ merge_batch_data_with_parent!(batch_data, data[batch_data._request.options[:merge_with_index]])
295
301
  end
296
302
  end
297
303
 
@@ -338,11 +344,6 @@ class LHS::Record
338
344
  data
339
345
  end
340
346
 
341
- # Checks if given raw is paginated or not
342
- def paginated?(raw)
343
- !!(raw.is_a?(Hash) && raw.dig(*total_key))
344
- end
345
-
346
347
  def prepare_options_for_include_all_request!(options)
347
348
  if options.is_a?(Array)
348
349
  options.each do |option|
@@ -439,7 +440,7 @@ class LHS::Record
439
440
  end.flatten
440
441
  end
441
442
 
442
- def options_for_next_batch(record, pagination, options, parent_data = nil)
443
+ def options_for_next_batch(record, pagination, options)
443
444
  batch_options = []
444
445
  pagination.pages_left.times do |index|
445
446
  page_options = {
@@ -448,7 +449,6 @@ class LHS::Record
448
449
  record.pagination_key(:parameter) => pagination.next_offset(index + 1)
449
450
  }
450
451
  }
451
- page_options[:parent_data] = parent_data if parent_data
452
452
  batch_options.push(
453
453
  options.deep_dup.deep_merge(page_options)
454
454
  )
data/lib/lhs/record.rb CHANGED
@@ -19,6 +19,8 @@ class LHS::Record
19
19
  'lhs/concerns/record/find_by'
20
20
  autoload :First,
21
21
  'lhs/concerns/record/first'
22
+ autoload :Last,
23
+ 'lhs/concerns/record/last'
22
24
  autoload :Mapping,
23
25
  'lhs/concerns/record/mapping'
24
26
  autoload :Model,
@@ -49,6 +51,7 @@ class LHS::Record
49
51
  include Find
50
52
  include FindBy
51
53
  include First
54
+ include Last
52
55
  include LHS::Inspect
53
56
  include Mapping
54
57
  include Model
data/lib/lhs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LHS
2
- VERSION = '15.4.1'
2
+ VERSION = '15.5.0'
3
3
  end
@@ -33,8 +33,8 @@ describe LHS::Data do
33
33
  context 'collections' do
34
34
  it 'forwards calls to the collection' do
35
35
  expect(data.count).to be_kind_of Integer
36
- expect(data[0]).to be_kind_of LHS::Data
37
- expect(data.sample).to be_kind_of LHS::Data
36
+ expect(data[0]).to be_kind_of Record
37
+ expect(data.sample).to be_kind_of Record
38
38
  end
39
39
 
40
40
  it 'provides a total method to get the number of total records' do
@@ -0,0 +1,66 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHS::Record do
4
+
5
+ context 'last' do
6
+
7
+ context 'for not paginated endpoints' do
8
+
9
+ before do
10
+ class Sector < LHS::Record
11
+ endpoint 'http://services/sectors'
12
+ end
13
+
14
+ stub_request(:get, "http://services/sectors?limit=1")
15
+ .to_return(
16
+ body: [{ number: 1 }, { number: 2 }, { number: 3 }].to_json
17
+ )
18
+ end
19
+
20
+ it 'returns the last record from the already complete collection' do
21
+ sector = Sector.last
22
+ expect(sector).to be_kind_of Sector
23
+ expect(sector.number).to eq 3
24
+ end
25
+ end
26
+
27
+ context 'for paginated endpoints' do
28
+
29
+ before do
30
+ class Place < LHS::Record
31
+ endpoint 'http://datastore/places'
32
+ end
33
+
34
+ stub_request(:get, "http://datastore/places?limit=1")
35
+ .to_return(
36
+ body: {
37
+ items: [
38
+ { id: 'first-1', company_name: 'Localsearch AG' }
39
+ ],
40
+ total: 500,
41
+ limit: 1,
42
+ offset: 0
43
+ }.to_json
44
+ )
45
+
46
+ stub_request(:get, "http://datastore/places?limit=1&offset=499")
47
+ .to_return(
48
+ body: {
49
+ items: [
50
+ { id: 'last-500', company_name: 'Curious GmbH' }
51
+ ],
52
+ total: 500,
53
+ limit: 1,
54
+ offset: 0
55
+ }.to_json
56
+ )
57
+ end
58
+
59
+ it 'returns the last record from the already complete collection' do
60
+ place = Place.last
61
+ expect(place).to be_kind_of Place
62
+ expect(place.id).to eq 'last-500'
63
+ end
64
+ end
65
+ end
66
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhs
3
3
  version: !ruby/object:Gem::Version
4
- version: 15.4.1
4
+ version: 15.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhs/graphs/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-19 00:00:00.000000000 Z
11
+ date: 2018-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -238,6 +238,7 @@ files:
238
238
  - lib/lhs/concerns/record/find.rb
239
239
  - lib/lhs/concerns/record/find_by.rb
240
240
  - lib/lhs/concerns/record/first.rb
241
+ - lib/lhs/concerns/record/last.rb
241
242
  - lib/lhs/concerns/record/mapping.rb
242
243
  - lib/lhs/concerns/record/model.rb
243
244
  - lib/lhs/concerns/record/pagination.rb
@@ -400,6 +401,7 @@ files:
400
401
  - spec/record/includes_warning_spec.rb
401
402
  - spec/record/item_key_spec.rb
402
403
  - spec/record/items_created_key_configuration_spec.rb
404
+ - spec/record/last_spec.rb
403
405
  - spec/record/loading_twice_spec.rb
404
406
  - spec/record/mapping_spec.rb
405
407
  - spec/record/model_name_spec.rb
@@ -455,7 +457,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
455
457
  requirements:
456
458
  - Ruby >= 2.3.0
457
459
  rubyforge_project:
458
- rubygems_version: 2.6.14
460
+ rubygems_version: 2.7.6
459
461
  signing_key:
460
462
  specification_version: 4
461
463
  summary: Rails gem providing an easy, active-record-like interface for http json services
@@ -592,6 +594,7 @@ test_files:
592
594
  - spec/record/includes_warning_spec.rb
593
595
  - spec/record/item_key_spec.rb
594
596
  - spec/record/items_created_key_configuration_spec.rb
597
+ - spec/record/last_spec.rb
595
598
  - spec/record/loading_twice_spec.rb
596
599
  - spec/record/mapping_spec.rb
597
600
  - spec/record/model_name_spec.rb