lhs 15.4.1 → 15.5.0

Sign up to get free protection for your applications and to get access to all the features.
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