batch-loader 1.1.1 → 1.2.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: 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