n1_loader 1.0.0 → 1.1.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
  SHA256:
3
- metadata.gz: e86d093c173eed577feb029f483c8b283f516bba1611391f9036e5675dec91d5
4
- data.tar.gz: 626e0305af7e75fd6a5dbb23d6970a8972ca292a9449f2f32d61cf7849c57ec9
3
+ metadata.gz: 8a365bb6b58a962185cd24033f6dd6cb98510712973dacdea4977a3121b64adc
4
+ data.tar.gz: d06031503475dc13f52acddb881931de5b7dd244acab6b46553d4a73c8efbd2d
5
5
  SHA512:
6
- metadata.gz: 3b450b20c25c935d3644003bf320e50644376cb6fc77cbda414522947a50857c3b28c5607bbcfd484dd9626a64523726cb4c6dd98b402a9ed3b73f1d6a40785a
7
- data.tar.gz: 9d07c4a64e89f2c2e9aa230d86c780388aaf720002db5fac37fe9b98ffd6297b914ab49ec54306c728c3457ea7a323a52d66c3c9e78c40ccbaed0a511be1f012
6
+ metadata.gz: 9172c4cd233739a0ebc379b3988037349d028020d5eb066642532f2b3da2a75d3faa34edd872aa5b5925eed91509c2c3a202e7a9aa448ca5020435b4f5e9c5a5
7
+ data.tar.gz: e74f92e69f47909b812adecb1aa7dc319c090a2ad865e89732a4ebdbbd378c02dbec28cc7ff5b0ff42262acf3a07e8deb8a4a949634d70c6d6c3986837a6ab5d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [1.1.0] - 2021-12-27
2
+
3
+ - Introduce `fulfill` method to abstract the storage.
4
+
1
5
  ## [1.0.0] - 2021-12-26
2
6
 
3
7
  - Various of great features.
data/README.md CHANGED
@@ -47,8 +47,7 @@ class Example
47
47
 
48
48
  # with inline loader
49
49
  n1_loader :anything do |elements|
50
- # Has to return a hash that has keys as element from elements
51
- elements.group_by(&:itself)
50
+ elements.each { |element| fulfill(element, [element]) }
52
51
  end
53
52
 
54
53
  # with custom loader
@@ -57,9 +56,8 @@ end
57
56
 
58
57
  # Custom loader that can be shared with many classes
59
58
  class MyLoader < N1Loader::Loader
60
- # Has to return a hash that has keys as element from elements
61
59
  def perform(elements)
62
- elements.group_by(&:itself)
60
+ elements.each { |element| fulfill(element, [element]) }
63
61
  end
64
62
  end
65
63
 
@@ -80,8 +78,7 @@ class Example
80
78
  include N1Loader::Loadable
81
79
 
82
80
  n1_loader :anything do |elements|
83
- # Has to return a hash that has keys as element from elements
84
- elements.group_by(&:itself)
81
+ elements.each { |element| fulfill(element, [element]) }
85
82
  end
86
83
  end
87
84
 
@@ -99,8 +96,7 @@ objects.map(&:anything) # => loading happen for the first time (without N+1)
99
96
  ```ruby
100
97
  class MyLoader < N1Loader::Loader
101
98
  def perform(elements)
102
- # Has to return a hash that has keys as element from elements
103
- elements.group_by(&:itself)
99
+ elements.each { |element| fulfill(element, [element]) }
104
100
  end
105
101
  end
106
102
 
@@ -128,8 +124,7 @@ class Example
128
124
 
129
125
  # with inline loader
130
126
  n1_loader :anything do |elements|
131
- # Has to return a hash that has keys as element from elements
132
- elements.group_by(&:itself)
127
+ elements.each { |element| fulfill(element, [element]) }
133
128
  end
134
129
  end
135
130
 
@@ -151,8 +146,7 @@ objects.map(&:anything) # => new loader was executed first time without N+1 issu
151
146
  ```ruby
152
147
  class MyLoader < N1Loader::Loader
153
148
  def perform(elements)
154
- # Has to return a hash that has keys as element from elements
155
- elements.group_by(&:itself)
149
+ elements.each { |element| fulfill(element, [element]) }
156
150
  end
157
151
  end
158
152
 
@@ -171,14 +165,13 @@ class Example
171
165
 
172
166
  n1_loader :something do # no arguments passed to the block, so we can override both perform and single.
173
167
  def perform(elements)
174
- # Has to return a hash that has keys as element from elements
175
- elements.group_by(&:itself)
168
+ elements.each { |element| fulfill(element, [element]) }
176
169
  end
177
170
 
178
171
  # Optimized for single object loading
179
172
  def single(element)
180
173
  # Just return a value you want to have for this element
181
- element
174
+ [element]
182
175
  end
183
176
  end
184
177
  end
@@ -206,8 +199,7 @@ class User < ActiveRecord::Base
206
199
  n1_loader :orders_count do |users|
207
200
  hash = Order.where(user: users).group(:user_id).count
208
201
 
209
- # hash has to have keys as initial elements
210
- hash.transform_keys! { |key| users.find { |user| user.id == key } }
202
+ users.each { |user| fulfill(user, hash[user.id]) }
211
203
  end
212
204
  end
213
205
 
@@ -234,9 +226,8 @@ class User < ActiveRecord::Base
234
226
 
235
227
  n1_loader :orders_count do |users|
236
228
  hash = Order.where(user: users).group(:user_id).count
237
-
238
- # hash has to have keys as initial elements
239
- hash.transform_keys! { |key| users.find { |user| user.id == key } }
229
+
230
+ users.each { |user| fulfill(user, hash[user.id]) }
240
231
  end
241
232
  end
242
233
 
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ N1Loader::Loader.define_method :preloaded_records do
4
+ @preloaded_records ||= loaded.values
5
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "../n1_loader"
4
-
4
+ require_relative "active_record/loader"
5
5
  require "active_record"
6
6
 
7
7
  ActiveSupport.on_load(:active_record) do
@@ -8,9 +8,7 @@ module N1Loader
8
8
  #
9
9
  # # with inline loader
10
10
  # n1_loader :something do |elements|
11
- # elements.each_with_object({}) do |element, hash|
12
- # hash[element] = element.calculate_something
13
- # end
11
+ # elements.each { |element| fulfill(element,, element.calculate_something) }
14
12
  # end
15
13
  #
16
14
  # # with custom loader
@@ -20,9 +18,7 @@ module N1Loader
20
18
  # # custom loader
21
19
  # class MyLoader < N1Loader::Loader
22
20
  # def perform(elements)
23
- # elements.each_with_object({}) do |element, hash|
24
- # hash[element] = element.calculate_something
25
- # end
21
+ # elements.each { |element| fulfill(element,, element.calculate_something) }
26
22
  # end
27
23
  # end
28
24
  module Loadable
@@ -10,30 +10,39 @@ module N1Loader
10
10
  @elements = elements
11
11
  end
12
12
 
13
- def perform(_elements)
14
- raise NotImplemented, "Subclasses have to implement the method"
13
+ def for(element)
14
+ if loaded.empty? && elements.any?
15
+ raise NotFilled, "Nothing was preloaded, perhaps you forgot to use fulfill method"
16
+ end
17
+ raise NotLoaded, "The data was not preloaded for the given element" unless loaded.key?(element)
18
+
19
+ loaded[element]
15
20
  end
16
21
 
17
- def loaded
18
- @loaded ||= if elements.size == 1 && respond_to?(:single)
19
- { elements.first => single(elements.first) }
20
- else
21
- perform(elements)
22
- end
22
+ private
23
+
24
+ attr_reader :elements
25
+
26
+ def perform(_elements)
27
+ raise NotImplemented, "Subclasses have to implement the method"
23
28
  end
24
29
 
25
- def preloaded_records
26
- @preloaded_records ||= loaded.values
30
+ def fulfill(element, value)
31
+ @loaded[element] = value
27
32
  end
28
33
 
29
- def for(element)
30
- raise NotLoaded, "The data was not preloaded for the given element" unless elements.include?(element)
34
+ def loaded
35
+ return @loaded if @loaded
31
36
 
32
- loaded.compare_by_identity[element]
33
- end
37
+ @loaded = {}.compare_by_identity
34
38
 
35
- private
39
+ if elements.size == 1 && respond_to?(:single)
40
+ fulfill(elements.first, single(elements.first))
41
+ elsif elements.any?
42
+ perform(elements)
43
+ end
36
44
 
37
- attr_reader :elements
45
+ @loaded
46
+ end
38
47
  end
39
48
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module N1Loader
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
data/lib/n1_loader.rb CHANGED
@@ -10,4 +10,5 @@ module N1Loader # :nodoc:
10
10
  class Error < StandardError; end
11
11
  class NotImplemented < Error; end
12
12
  class NotLoaded < Error; end
13
+ class NotFilled < Error; end
13
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: n1_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Demin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-26 00:00:00.000000000 Z
11
+ date: 2021-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -147,6 +147,7 @@ files:
147
147
  - lib/n1_loader/active_record.rb
148
148
  - lib/n1_loader/active_record/associations_preloader_v5.rb
149
149
  - lib/n1_loader/active_record/associations_preloader_v6.rb
150
+ - lib/n1_loader/active_record/loader.rb
150
151
  - lib/n1_loader/ar_lazy_preload.rb
151
152
  - lib/n1_loader/ar_lazy_preload/associated_context_builder.rb
152
153
  - lib/n1_loader/ar_lazy_preload/context_adapter.rb