lhs 3.3.6 → 3.4.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
2
  SHA1:
3
- metadata.gz: e6e194ca0104d33690c704260ef36ef265ab9979
4
- data.tar.gz: 63de1464cea6731ab54c58e01c5ef46d74d6b46c
3
+ metadata.gz: c6ba978add2aba0196bb5d98ecb6e114445db064
4
+ data.tar.gz: be48ebe2badd12166f55dac56e6579bef5fbed77
5
5
  SHA512:
6
- metadata.gz: 71f0954b3bea0a23ba9f8c6169e86df4a92b4d81b8702f3634eeb770b9e989a0b4795703f2de97b533ffd521711fac0a54a5e540426978a55413c83c393f0cce
7
- data.tar.gz: 84ac812bc020fe427adc6d34ae0d87a1c528701b8cb644da0bfe50b613e7a12dd7eb0bcf00c5c8b046afb024fb6d112cd36cbe729dbb2f89c39479fa8bb0e66b
6
+ metadata.gz: e96f1f2d0baa2658854f73222e50a7569ccc5afd4075614eaadb99f656afbe041f839ca7332f358a41e7e3fad18d5f30e1b90724ba4dac5dd9969ca42ceab61a
7
+ data.tar.gz: 960bce0293960b60fd428d80d272038db342001416ab93cd00f5715e3a7eb1ee96d1f7d28456dbbc89163e2f3e81e6611060bb596be8040c060086794a0cf0ab
data/README.md CHANGED
@@ -368,7 +368,24 @@ Feedback.where(limit: 50, offset: 51)
368
368
  `limit` provides amount of items per page.
369
369
  `offset` provides how many items where skipped to start the current page.
370
370
 
371
- ## Partial Kaminari support
371
+ ### Configure the name of the keys for offset, limit, total and name of items
372
+
373
+ Endpoints provide different interfaces to deal with paginated resources.
374
+ They differ for example for the key that is used for providing the current page items, the total amount of items, the current page size etc.
375
+ In order to have `LHS::Record` deal with those different interfaces you can configure it:
376
+
377
+ ```ruby
378
+ class Search < LHS::Record
379
+ configuration items: :docs, limit: :size, offset: :start, total: :totalResults
380
+ endpoint ':search/:type'
381
+ end
382
+ ```
383
+ `items` key used to determine items of the current page.
384
+ `limit` key used to work with page limits.
385
+ `offset` key used to paginate multiple pages.
386
+ `total` key used to determine the total amount of items.
387
+
388
+ ### Partial Kaminari support
372
389
 
373
390
  LHS implements an interface that makes it partially working with Kaminari.
374
391
 
@@ -384,7 +401,7 @@ For example, you can use kaminari to render paginations based on LHS Records:
384
401
  = paginate @items
385
402
  ```
386
403
 
387
- ## form_for Helper
404
+ ### form_for Helper
388
405
  Rails `form_for` view-helper can be used in combination with instances of LHS::Record to autogenerate forms:
389
406
  ```
390
407
  <%= form_for(@instance, url: '/create') do |f| %>
@@ -7,17 +7,18 @@ class LHS::Collection < LHS::Proxy
7
7
  include InternalCollection
8
8
 
9
9
  delegate :select, to: :_collection
10
+ delegate :_record, to: :_data
10
11
 
11
12
  def total
12
- _data._raw[:total]
13
+ _data._raw[_record.total_key]
13
14
  end
14
15
 
15
16
  def limit
16
- _data._raw[:limit]
17
+ _data._raw[_record.limit_key]
17
18
  end
18
19
 
19
20
  def offset
20
- _data._raw[:offset]
21
+ _data._raw[_record.offset_key]
21
22
  end
22
23
 
23
24
  def href
@@ -26,8 +27,8 @@ class LHS::Collection < LHS::Proxy
26
27
 
27
28
  def _collection
28
29
  raw = _data._raw if _data._raw.is_a?(Array)
29
- raw ||= _data._raw[:items]
30
- Collection.new(raw, _data, _data._record_class)
30
+ raw ||= _data._raw[_record.items_key]
31
+ Collection.new(raw, _data, _record)
31
32
  end
32
33
 
33
34
  delegate :_raw, to: :_data
@@ -7,8 +7,7 @@ class LHS::Item < LHS::Proxy
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  def destroy
10
- record = _data._root._record_class
11
- _data._request = record.request(method: :delete, url: href)._request
10
+ _data._request = _data.class.request(method: :delete, url: href)._request
12
11
  _data
13
12
  end
14
13
  end
@@ -14,7 +14,7 @@ class LHS::Item < LHS::Proxy
14
14
  end
15
15
 
16
16
  def save!
17
- record = _data._root._record_class
17
+ record = _data.class
18
18
  data = _data._raw.dup
19
19
  url =
20
20
  if href.present?
@@ -14,9 +14,8 @@ class LHS::Item < LHS::Proxy
14
14
  end
15
15
 
16
16
  def update!(params)
17
- record = _data._root._record_class
18
- _data.merge_raw!(LHS::Data.new(params))
19
- response_data = record.request(
17
+ _data.merge_raw!(LHS::Data.new(params, _data.parent, _data.class))
18
+ response_data = _data.class.request(
20
19
  method: :post,
21
20
  url: href,
22
21
  body: _data.to_json,
@@ -30,7 +30,7 @@ class LHS::Item < LHS::Proxy
30
30
  private
31
31
 
32
32
  def validation_endpoint
33
- endpoint = _data._record_class.find_endpoint(_data._raw)
33
+ endpoint = _data._record.find_endpoint(_data._raw)
34
34
  endpoint ||= LHS::Endpoint.for_url(_data.href) if _data.href
35
35
  validates = endpoint.options && endpoint.options.fetch(:validates, false)
36
36
  fail 'Endpoint does not support validations!' unless validates
@@ -5,6 +5,8 @@ class LHS::Record
5
5
  module All
6
6
  extend ActiveSupport::Concern
7
7
 
8
+ DEFAULT_LIMIT = 100
9
+
8
10
  module ClassMethods
9
11
  # Should be an edge case but sometimes all objects from a certain resource
10
12
  # are required. In this case we load the first page with the default max limit,
@@ -12,12 +14,10 @@ class LHS::Record
12
14
  # for the following pages and concatenate all the results in order to return
13
15
  # all the objects for a given resource.
14
16
  def all(params = {})
15
- all = []
16
- default_max_limit = 100
17
- data = request(params: params.merge(limit: default_max_limit))
18
- all.concat(all_items_from(data))
19
- request_all_the_rest(data, all, params) if data._raw.is_a?(Hash) && data._raw[:total]
20
- data._record_class.new(LHS::Data.new(all, nil, self))
17
+ limit = params[limit_key] || DEFAULT_LIMIT
18
+ data = request(params: params.merge(limit_key => limit))
19
+ request_all_the_rest(data, params) if data._raw.is_a?(Hash) && data._raw[total_key]
20
+ data._record.new(LHS::Data.new(data, nil, self))
21
21
  end
22
22
 
23
23
  private
@@ -26,18 +26,23 @@ class LHS::Record
26
26
  if data._raw.is_a?(Array)
27
27
  data._raw
28
28
  else
29
- data._raw[:items]
29
+ data._raw[items_key]
30
30
  end
31
31
  end
32
32
 
33
- def request_all_the_rest(data, all, params)
34
- total_left = data._raw[:total] - data.count
35
- limit = data._raw[:limit] || data.count
33
+ def request_all_the_rest(data, params)
34
+ total_left = data._raw[total_key] - data.count
35
+ limit = data._raw[limit_key] || data.count
36
36
  if limit > 0
37
37
  requests = total_left / limit
38
38
  requests.times do |i|
39
39
  offset = limit * (i + 1) + 1
40
- all.concat request(params: params.merge(limit: limit, offset: offset))._raw[:items]
40
+ data._raw[items_key].concat all_items_from request(
41
+ params: params.merge(
42
+ data._record.limit_key => limit,
43
+ data._record.offset_key => offset
44
+ )
45
+ )
41
46
  end
42
47
  end
43
48
  end
@@ -8,10 +8,10 @@ class LHS::Record
8
8
  module ClassMethods
9
9
  # Process single entries fetched in batches
10
10
  def find_each(options = {})
11
- find_in_batches(options) do |data|
12
- data.each do |record|
13
- item = LHS::Item.new(LHS::Data.new(record, data, self))
14
- yield new(LHS::Data.new(item, data, self))
11
+ find_in_batches(options) do |records|
12
+ records.each do |record|
13
+ item = LHS::Item.new(record)
14
+ yield new(LHS::Data.new(item, records._data, self))
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,34 @@
1
+ require 'active_support'
2
+
3
+ class LHS::Record
4
+
5
+ # Allows configuring endpoints
6
+ # like which keys are used for the items, offset, total etc.
7
+ module Configuration
8
+ extend ActiveSupport::Concern
9
+
10
+ mattr_accessor :configuration
11
+
12
+ module ClassMethods
13
+ def configuration(args)
14
+ @configuration ||= args.freeze || {}
15
+ end
16
+
17
+ def items_key
18
+ @configuration.try(:[], :items) || :items
19
+ end
20
+
21
+ def limit_key
22
+ @configuration.try(:[], :limit) || :limit
23
+ end
24
+
25
+ def total_key
26
+ @configuration.try(:[], :total) || :total
27
+ end
28
+
29
+ def offset_key
30
+ @configuration.try(:[], :offset) || :offset
31
+ end
32
+ end
33
+ end
34
+ end
@@ -13,13 +13,13 @@ class LHS::Record
13
13
  data = LHS::Data.new(json, nil, self, e.response.request)
14
14
  item = LHS::Item.new(data)
15
15
  item.errors = LHS::Errors.new(e.response)
16
- data._record_class.new(LHS::Data.new(item, data))
16
+ data._record.new(LHS::Data.new(item, data))
17
17
  end
18
18
 
19
19
  def create!(data = {})
20
20
  url = compute_url!(data)
21
21
  data = request(url: url, method: :post, body: data.to_json, headers: { 'Content-Type' => 'application/json' })
22
- data._record_class.new(data)
22
+ data._record.new(data)
23
23
  end
24
24
  end
25
25
  end
@@ -31,7 +31,7 @@ class LHS::Record
31
31
 
32
32
  def for_url(url)
33
33
  return unless url
34
- _template, record = LHS::Record::Endpoints.all.detect do |template, _record_class|
34
+ _template, record = LHS::Record::Endpoints.all.detect do |template, _|
35
35
  LHC::Endpoint.match?(url, template)
36
36
  end
37
37
  record
@@ -14,8 +14,8 @@ class LHS::Record
14
14
  else
15
15
  find_by_id(args)
16
16
  end
17
- return data unless data._record_class
18
- data._record_class.new(data)
17
+ return data unless data._record
18
+ data._record.new(data)
19
19
  end
20
20
 
21
21
  private
@@ -26,7 +26,7 @@ class LHS::Record
26
26
  if data._proxy.is_a?(LHS::Collection)
27
27
  data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
28
28
  else
29
- data._record_class.new(data)
29
+ data._record.new(data)
30
30
  end
31
31
  end
32
32
  end
@@ -9,7 +9,7 @@ class LHS::Record
9
9
  # Used to query data from the service.
10
10
  def where(params = {})
11
11
  data = request(params: params)
12
- data._record_class.new(data)
12
+ data._record.new(data)
13
13
  end
14
14
  end
15
15
  end
data/lib/lhs/data.rb CHANGED
@@ -5,14 +5,16 @@ Dir[File.dirname(__FILE__) + '/concerns/data/*.rb'].each { |file| require file }
5
5
  class LHS::Data
6
6
  include Json
7
7
 
8
+ delegate :instance_methods, :items_key, :limit_key, :total_key, :offset_key, to: :class
9
+
8
10
  # prevent clashing with attributes of underlying data
9
- attr_accessor :_proxy, :_raw, :_parent, :_record_class, :_request
11
+ attr_accessor :_proxy, :_raw, :_parent, :_record, :_request
10
12
 
11
13
  def initialize(input, parent = nil, record = nil, request = nil)
12
14
  self._raw = raw_from_input(input)
13
- self._proxy = proxy_from_input(input)
14
- self._record_class = record
15
15
  self._parent = parent
16
+ self._record = record
17
+ self._proxy = proxy_from_input(input)
16
18
  self._request = request
17
19
  end
18
20
 
@@ -30,7 +32,7 @@ class LHS::Data
30
32
  end
31
33
 
32
34
  def class
33
- _root._record_class
35
+ _root._record
34
36
  end
35
37
 
36
38
  # enforce internal data structure to have deep symbolized keys
@@ -50,14 +52,14 @@ class LHS::Data
50
52
  end
51
53
 
52
54
  def respond_to_missing?(name, include_all = false)
53
- (root_item? && _root._record_class.instance_methods.include?(name)) ||
55
+ (root_item? && instance_methods.include?(name)) ||
54
56
  _proxy.respond_to?(name, include_all)
55
57
  end
56
58
 
57
59
  private
58
60
 
59
61
  def collection_proxy?(input)
60
- !! (input.is_a?(Hash) && input[:items]) || input.is_a?(Array) || _raw.is_a?(Array)
62
+ !! (input.is_a?(Hash) && input[items_key]) || input.is_a?(Array) || _raw.is_a?(Array)
61
63
  end
62
64
 
63
65
  def root_item
data/lib/lhs/endpoint.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  class LHS::Endpoint
3
3
 
4
4
  def self.for_url(url)
5
- template, record = LHS::Record::Endpoints.all.detect do |template, _record_class|
5
+ template, record = LHS::Record::Endpoints.all.detect do |template, _record|
6
6
  LHC::Endpoint.match?(url, template)
7
7
  end
8
8
  record.endpoints.detect { |endpoint| endpoint.url == template } if record
data/lib/lhs/proxy.rb CHANGED
@@ -17,8 +17,7 @@ class LHS::Proxy
17
17
 
18
18
  def reload!
19
19
  fail 'No href found' unless _data.href
20
- record = _data._root._record_class
21
- data = record.request(url: _data.href, method: :get)
20
+ data = _data.class.request(url: _data.href, method: :get)
22
21
  _data.merge_raw!(data)
23
22
  self._loaded = true
24
23
  self
data/lib/lhs/record.rb CHANGED
@@ -3,6 +3,7 @@ Dir[File.dirname(__FILE__) + '/concerns/record/*.rb'].each { |file| require file
3
3
  class LHS::Record
4
4
  include All
5
5
  include Batch
6
+ include Configuration
6
7
  include Create
7
8
  include Endpoints
8
9
  include Find
data/lib/lhs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LHS
2
- VERSION = "3.3.6"
2
+ VERSION = "3.4.0"
3
3
  end
@@ -0,0 +1,44 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHS::Collection do
4
+ let(:search) { 'http://local.ch/search' }
5
+ let(:limit) { 10 }
6
+ let(:total) { 20 }
7
+ let(:offset) { 0 }
8
+ let(:first_response_data) do
9
+ {
10
+ docs: (1..10).to_a,
11
+ start: offset,
12
+ size: limit,
13
+ totalResults: total
14
+ }
15
+ end
16
+ let(:second_response_data) do
17
+ {
18
+ docs: (11..20).to_a,
19
+ start: offset,
20
+ size: limit,
21
+ totalResults: total
22
+ }
23
+ end
24
+
25
+ before(:each) do
26
+ LHC.config.placeholder('search', search)
27
+ class Search < LHS::Record
28
+ configuration items: :docs, limit: :size, offset: :start, total: :totalResults
29
+ endpoint ':search/:type'
30
+ end
31
+ stub_request(:get, "http://local.ch/search/phonebook?size=10").to_return(body: first_response_data.to_json)
32
+ stub_request(:get, "http://local.ch/search/phonebook?size=10&start=11").to_return(body: second_response_data.to_json)
33
+ end
34
+
35
+ context 'lets you configure how to deal with collections' do
36
+ it 'initalises and gives access to collections according to configuration' do
37
+ results = Search.all(type: :phonebook, size: 10)
38
+ expect(results.count).to eq total
39
+ expect(results.total).to eq total
40
+ expect(results.limit).to eq limit
41
+ expect(results.offset).to eq offset
42
+ end
43
+ end
44
+ end
@@ -6,7 +6,13 @@ describe LHS::Data do
6
6
  end
7
7
 
8
8
  let(:data) do
9
- LHS::Data.new(json)
9
+ LHS::Data.new(json, nil, Record)
10
+ end
11
+
12
+ before(:each) do
13
+ class Record < LHS::Record
14
+ endpoint ':datastore/v2/data'
15
+ end
10
16
  end
11
17
 
12
18
  context 'collections' do
@@ -10,15 +10,12 @@ describe LHS::Data do
10
10
  end
11
11
 
12
12
  let(:data_from_raw) do
13
- LHS::Data.new(
14
- href: 'http://www.local.ch/v2/stuff',
15
- id: '123123123'
16
- )
13
+ LHS::Data.new({ href: 'http://www.local.ch/v2/stuff', id: '123123123' }, nil, Record)
17
14
  end
18
15
 
19
16
  let(:data_from_item) do
20
17
  raw = { href: 'http://www.local.ch/v2/stuff' }
21
- item = LHS::Item.new(LHS::Data.new(raw))
18
+ item = LHS::Item.new(LHS::Data.new(raw, nil, Record))
22
19
  LHS::Data.new(item)
23
20
  end
24
21
 
@@ -6,7 +6,13 @@ describe LHS::Data do
6
6
  end
7
7
 
8
8
  let(:data) do
9
- LHS::Data.new(raw)
9
+ LHS::Data.new(raw, nil, Record)
10
+ end
11
+
12
+ before(:each) do
13
+ class Record < LHS::Record
14
+ endpoint ':datastore/v2/data'
15
+ end
10
16
  end
11
17
 
12
18
  context 'select' do
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: 3.3.6
4
+ version: 3.4.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: 2016-03-07 00:00:00.000000000 Z
11
+ date: 2016-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lhc
@@ -186,6 +186,7 @@ files:
186
186
  - lib/lhs/concerns/item/validation.rb
187
187
  - lib/lhs/concerns/record/all.rb
188
188
  - lib/lhs/concerns/record/batch.rb
189
+ - lib/lhs/concerns/record/configuration.rb
189
190
  - lib/lhs/concerns/record/create.rb
190
191
  - lib/lhs/concerns/record/endpoints.rb
191
192
  - lib/lhs/concerns/record/find.rb
@@ -207,6 +208,7 @@ files:
207
208
  - script/ci/build.sh
208
209
  - spec/.DS_Store
209
210
  - spec/collection/collection_items_spec.rb
211
+ - spec/collection/configurable_spec.rb
210
212
  - spec/collection/delegate_spec.rb
211
213
  - spec/collection/enumerable_spec.rb
212
214
  - spec/collection/meta_data_spec.rb
@@ -331,6 +333,7 @@ summary: Rails gem providing an easy, active-record-like interface to use http b
331
333
  services
332
334
  test_files:
333
335
  - spec/collection/collection_items_spec.rb
336
+ - spec/collection/configurable_spec.rb
334
337
  - spec/collection/delegate_spec.rb
335
338
  - spec/collection/enumerable_spec.rb
336
339
  - spec/collection/meta_data_spec.rb