batch-loader 1.0.4 → 1.1.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
2
  SHA1:
3
- metadata.gz: 68e25c611b667937e94fa71fc53d7ca0e0610914
4
- data.tar.gz: bf88a43be0f71991ea587d9f1a9cd7de0c63310c
3
+ metadata.gz: 124dbf8b2fa20f0e0fd6bca686449f48c3dd3625
4
+ data.tar.gz: d10abd20d3f55f64871673b5410c8d92539abaa5
5
5
  SHA512:
6
- metadata.gz: 23317a63530d9067930446a9426f34f54b78d8a991c2901558b1c79558b7941291dedbfd58b843195cae19e6fac4288668a7176273c64320419dc4621ac23a16
7
- data.tar.gz: 5ce2b962b3948e6a579b1631e500d81c3a48e0eaa7bddf22fbbf00d081c39fda88beb6803531848fce5aa5bbe6e9ac243aaa69174e1127b5109cf7a1cd70cc96
6
+ metadata.gz: 4e97a8dcbb31e6310dc2b40df35143f6bdac4a1153b1ea9de175f07b36e8df0da7890e1c445f91c782e3ac1804ee0129107329685e0aac50dcafadbe17278c3a
7
+ data.tar.gz: 93188a2738ac3f57735e0643003818b19eb4875c2b748fbbf0e19751c837a8ba32247b84fa84533bb2bbe84515eb35fc28f31929813871c6eb21b9fc08a1d4b8
@@ -8,11 +8,16 @@ one of the following labels: `Added`, `Changed`, `Deprecated`,
8
8
  to manage the versions of this gem so
9
9
  that you can set version constraints properly.
10
10
 
11
- #### [Unreleased](https://github.com/exAspArk/batch-loader/compare/v1.0.4...HEAD)
11
+ #### [Unreleased](https://github.com/exAspArk/batch-loader/compare/v1.1.0...HEAD)
12
12
 
13
13
  * WIP
14
14
 
15
- #### [Unreleased](https://github.com/exAspArk/batch-loader/compare/v1.0.3...v1.0.4)
15
+ #### [v1.1.0](https://github.com/exAspArk/batch-loader/compare/v1.0.4...v1.1.0)
16
+
17
+ * `Added`: `default_value` override option. [#8](https://github.com/exAspArk/batch-loader/pull/8)
18
+ * `Added`: `loader.call {}` block syntax, for memoizing repeat calls to the same item. [#8](https://github.com/exAspArk/batch-loader/pull/8)
19
+
20
+ #### [v1.0.4](https://github.com/exAspArk/batch-loader/compare/v1.0.3...v1.0.4)
16
21
 
17
22
  * `Fixed`: Fix arity bug in `respond_to?` [#3](https://github.com/exAspArk/batch-loader/pull/3)
18
23
 
data/README.md CHANGED
@@ -17,6 +17,7 @@ This gem provides a generic lazy batching mechanism to avoid N+1 DB queries, HTT
17
17
  * [How it works](#how-it-works)
18
18
  * [RESTful API example](#restful-api-example)
19
19
  * [GraphQL example](#graphql-example)
20
+ * [Loading multiple items](#loading-multiple-items)
20
21
  * [Caching](#caching)
21
22
  * [Installation](#installation)
22
23
  * [Implementation details](#implementation-details)
@@ -279,6 +280,26 @@ end
279
280
 
280
281
  That's it.
281
282
 
283
+ ### Loading multiple items
284
+
285
+ For batches where there is no item in response to a call, we normally return `nil`. However, you can use `:default_value` to return something else instead:
286
+
287
+ ```ruby
288
+ BatchLoader.for(post.user_id).batch(default_value: NullUser.new) do |user_ids, loader|
289
+ User.where(id: user_ids).each { |user| loader.call(user.id, user) }
290
+ end
291
+ ```
292
+
293
+ For batches where the value is some kind of collection, such as an Array or Hash, `loader` also supports being called with a block, which yields the _current_ value, and returns the _next_ value. This is extremely useful for 1:Many relationships:
294
+
295
+ ```ruby
296
+ BatchLoader.for(user.id).batch(default_value: []) do |comment_ids, loader|
297
+ Comment.where(user_id: user_ids).each do |comment|
298
+ loader.call(user.id) { |memo| memo << comment }
299
+ end
300
+ end
301
+ ```
302
+
282
303
  ### Caching
283
304
 
284
305
  By default `BatchLoader` caches the loaded values. You can test it by running something like:
@@ -22,7 +22,8 @@ class BatchLoader
22
22
  @item = item
23
23
  end
24
24
 
25
- def batch(cache: true, &batch_block)
25
+ def batch(default_value: nil, cache: true, &batch_block)
26
+ @default_value = default_value
26
27
  @cache = cache
27
28
  @batch_block = batch_block
28
29
  __executor_proxy.add(item: @item)
@@ -75,12 +76,21 @@ class BatchLoader
75
76
  return if __executor_proxy.value_loaded?(item: @item)
76
77
 
77
78
  items = __executor_proxy.list_items
78
- loader = ->(item, value) { __executor_proxy.load(item: item, value: value) }
79
+ loader = -> (item, value = (no_value = true; nil), &block) {
80
+ if no_value && !block
81
+ raise ArgumentError, "Please pass a value or a block"
82
+ elsif block && !no_value
83
+ raise ArgumentError, "Please pass a value or a block, not both"
84
+ end
85
+
86
+ next_value = block ? block.call(__executor_proxy.loaded_value(item: item)) : value
87
+ __executor_proxy.load(item: item, value: next_value)
88
+ }
79
89
 
80
90
  @batch_block.call(items, loader)
81
91
  items.each do |item|
82
92
  next if __executor_proxy.value_loaded?(item: item)
83
- loader.call(item, nil) # use "nil" for not loaded item after succesfull batching
93
+ loader.call(item, @default_value)
84
94
  end
85
95
  __executor_proxy.delete(items: items)
86
96
  end
@@ -109,7 +119,7 @@ class BatchLoader
109
119
  def __executor_proxy
110
120
  @__executor_proxy ||= begin
111
121
  raise NoBatchError.new("Please provide a batch block first") unless @batch_block
112
- BatchLoader::ExecutorProxy.new(&@batch_block)
122
+ BatchLoader::ExecutorProxy.new(@default_value, &@batch_block)
113
123
  end
114
124
  end
115
125
 
@@ -4,9 +4,10 @@ require_relative "./executor"
4
4
 
5
5
  class BatchLoader
6
6
  class ExecutorProxy
7
- attr_reader :block, :global_executor
7
+ attr_reader :default_value, :block, :global_executor
8
8
 
9
- def initialize(&block)
9
+ def initialize(default_value, &block)
10
+ @default_value = default_value
10
11
  @block = block
11
12
  @block_hash_key = block.source_location
12
13
  @global_executor = BatchLoader::Executor.ensure_current
@@ -29,7 +30,11 @@ class BatchLoader
29
30
  end
30
31
 
31
32
  def loaded_value(item:)
32
- loaded[item]
33
+ if value_loaded?(item: item)
34
+ loaded[item]
35
+ else
36
+ @default_value.dup
37
+ end
33
38
  end
34
39
 
35
40
  def value_loaded?(item:)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class BatchLoader
4
- VERSION = "1.0.4"
4
+ VERSION = "1.1.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: batch-loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - exAspArk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-12 00:00:00.000000000 Z
11
+ date: 2017-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler