batch-loader 1.1.1 → 1.2.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: 0cb2bec5ff8fdc6fd2c2ec099c1db9ca07916594
4
- data.tar.gz: af763f4dc852c3f2b4ca73a3ce0ff639ea544f0a
3
+ metadata.gz: aa05684af093fc9efd4873f256fd0a173179609c
4
+ data.tar.gz: 9e7e5751b5bba6b43f0cf8bce0e32fd64885a194
5
5
  SHA512:
6
- metadata.gz: 699d6d95a80c2b7b7c366979277bb003c0eada94ea087df1812b2b1754ac70d6a518608bd25c7ae3d6665d6d0629c9836811c2e9d0e07bf3879064bf4f0b11c7
7
- data.tar.gz: 614b0b57b84e80a7f1de5af9d961c4ca78252e4c84e3a624fa49a25810acae7c6ec2648c8a573cddc2b9620896645d966d79b8c936c02f09b3cca0eb1a445d18
6
+ metadata.gz: '08d5499226c25e153e4587358e8f38cd88950fe4d216578ea5b82b71f77ca381bd07f0383bda26e54edd56ffb4c92b458028857f1db7d770101039c548d0838e'
7
+ data.tar.gz: '02913dc9ee5cc57e952ecd49a7636d275d7343990c574a3f14ff0ddf7ed662991cfdd4f8b722c0dcca54b86996d9a4377ebf4f5582075bf54670657dc8c0c30d'
@@ -8,10 +8,14 @@ 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.1.1...HEAD)
11
+ #### [Unreleased](https://github.com/exAspArk/batch-loader/compare/v1.2.0...HEAD)
12
12
 
13
13
  * WIP
14
14
 
15
+ #### [v1.2.0](https://github.com/exAspArk/batch-loader/compare/v1.1.1...v1.2.0)
16
+
17
+ * `Added`: `key` argument for the `BatchLoader#batch` method. [#12](https://github.com/exAspArk/batch-loader/pull/12)
18
+
15
19
  #### [v1.1.1](https://github.com/exAspArk/batch-loader/compare/v1.1.0...v1.1.1)
16
20
 
17
21
  * `Fixed`: `loader`, made it thread-safe again. [#10](https://github.com/exAspArk/batch-loader/pull/10)
data/README.md CHANGED
@@ -18,8 +18,10 @@ This gem provides a generic lazy batching mechanism to avoid N+1 DB queries, HTT
18
18
  * [RESTful API example](#restful-api-example)
19
19
  * [GraphQL example](#graphql-example)
20
20
  * [Loading multiple items](#loading-multiple-items)
21
+ * [Batch key](#batch-key)
21
22
  * [Caching](#caching)
22
23
  * [Installation](#installation)
24
+ * [API](#api)
23
25
  * [Implementation details](#implementation-details)
24
26
  * [Development](#development)
25
27
  * [Contributing](#contributing)
@@ -300,6 +302,30 @@ BatchLoader.for(user.id).batch(default_value: []) do |comment_ids, loader|
300
302
  end
301
303
  ```
302
304
 
305
+ ### Batch key
306
+
307
+ It's possible to reuse the same `BatchLoader#batch` block for loading different types of data by specifying a unique `key`.
308
+ For example, with polymorphic associations:
309
+
310
+ ```ruby
311
+ def lazy_association(post)
312
+ id = post.association_id
313
+ key = post.association_type
314
+
315
+ BatchLoader.for(id).batch(key: key) do |ids, loader, args|
316
+ model = Object.const_get(args[:key])
317
+ model.where(id: ids).each { |record| record.call(record.id, record) }
318
+ end
319
+ end
320
+ post1 = Post.save(association_id: 1, association_type: 'Tag')
321
+ post2 = Post.save(association_id: 1, association_type: 'Category')
322
+
323
+ lazy_association(post1) # SELECT * FROM tags WHERE id IN (1)
324
+ lazy_association(post2) # SELECT * FROM categories WHERE id IN (1)
325
+ ```
326
+
327
+ It's also required to pass custom `key` when using `BatchLoader` with metaprogramming (e.g. `eval`).
328
+
303
329
  ### Caching
304
330
 
305
331
  By default `BatchLoader` caches the loaded values. You can test it by running something like:
@@ -364,6 +390,24 @@ Or install it yourself as:
364
390
 
365
391
  $ gem install batch-loader
366
392
 
393
+ ## API
394
+
395
+ ```ruby
396
+ BatchLoader.for(item).batch(default_value: default_value, cache: cache, key: key) do |items, loader, args|
397
+ # ...
398
+ end
399
+ ```
400
+
401
+ | Argument Key | Default | Description |
402
+ | --------------- | --------------------------------------------- | ------------------------------------------------------------- |
403
+ | `item` | - | Item which will be collected and used for batching. |
404
+ | `default_value` | `nil` | Value returned by default after batching. |
405
+ | `cache` | `true` | Set `false` to disable caching between the same executions. |
406
+ | `key` | `nil` | Pass custom key to uniquely identify the batch block. |
407
+ | `items` | - | List of collected items for batching. |
408
+ | `loader` | - | Lambda which should be called to load values loaded in batch. |
409
+ | `args` | `{default_value: nil, cache: true, key: nil}` | Arguments passed to the `batch` method. |
410
+
367
411
  ## Implementation details
368
412
 
369
413
  See the [slides](https://speakerdeck.com/exaspark/batching-a-powerful-way-to-solve-n-plus-1-queries) [37-42].
@@ -23,9 +23,10 @@ class BatchLoader
23
23
  @__executor_proxy = executor_proxy
24
24
  end
25
25
 
26
- def batch(default_value: nil, cache: true, &batch_block)
26
+ def batch(default_value: nil, cache: true, key: nil, &batch_block)
27
27
  @default_value = default_value
28
28
  @cache = cache
29
+ @key = key
29
30
  @batch_block = batch_block
30
31
  __executor_proxy.add(item: @item)
31
32
 
@@ -78,7 +79,8 @@ class BatchLoader
78
79
 
79
80
  items = __executor_proxy.list_items
80
81
  loader = __loader
81
- @batch_block.call(items, loader)
82
+ args = {default_value: @default_value, cache: @cache, key: @key}
83
+ @batch_block.call(items, loader, args)
82
84
  items.each do |item|
83
85
  next if __executor_proxy.value_loaded?(item: item)
84
86
  loader.call(item, @default_value)
@@ -126,7 +128,7 @@ class BatchLoader
126
128
  def __executor_proxy
127
129
  @__executor_proxy ||= begin
128
130
  raise NoBatchError.new("Please provide a batch block first") unless @batch_block
129
- BatchLoader::ExecutorProxy.new(@default_value, &@batch_block)
131
+ BatchLoader::ExecutorProxy.new(@default_value, @key, &@batch_block)
130
132
  end
131
133
  end
132
134
 
@@ -6,10 +6,10 @@ class BatchLoader
6
6
  class ExecutorProxy
7
7
  attr_reader :default_value, :block, :global_executor
8
8
 
9
- def initialize(default_value, &block)
9
+ def initialize(default_value, key, &block)
10
10
  @default_value = default_value
11
11
  @block = block
12
- @block_hash_key = block.source_location
12
+ @block_hash_key = "#{key}#{block.source_location}"
13
13
  @global_executor = BatchLoader::Executor.ensure_current
14
14
  end
15
15
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class BatchLoader
4
- VERSION = "1.1.1"
4
+ VERSION = "1.2.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.1.1
4
+ version: 1.2.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-11-06 00:00:00.000000000 Z
11
+ date: 2017-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler