n1_loader 1.0.0 → 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
  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