n1_loader 1.3.0 → 1.4.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +15 -11
- data/lib/n1_loader/active_record/loader_collection.rb +1 -3
- data/lib/n1_loader/ar_lazy_preload/loader_collection_patch.rb +1 -1
- data/lib/n1_loader/core/loadable.rb +3 -3
- data/lib/n1_loader/core/loader.rb +44 -12
- data/lib/n1_loader/core/loader_collection.rb +2 -2
- data/lib/n1_loader/version.rb +1 -1
- data/lib/n1_loader.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d0f96166ae91c856012ea26c933cc56c7d33f68065b753a18adc3c6b9da7e87
|
4
|
+
data.tar.gz: adccc88c382d9283c2af9b41059298fa15563e47615678ef20629a0183a51253
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad3b1273627cf7abb5922cc7139c34e5e9543dc91d296d7e44deea690367d32082dd1ddc028ba40a4ed7fa402a65eb8f5aed36b6d8df0436937e59aaa6cef65a
|
7
|
+
data.tar.gz: fde03e325f2b780a070786f1648a98d278933c84b3266cedf4db50cd268b029839ff06290416846a9ab2a85a25a0795c30684845e4da15909417389dbd1a7a82
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## [1.4.0] - 2022-02-22
|
2
|
+
|
3
|
+
- add support of optional arguments
|
4
|
+
|
5
|
+
BREAKING CHANGES:
|
6
|
+
- rework arguments to use single definition through `argument <name>` only
|
7
|
+
- use keyword arguments
|
8
|
+
|
1
9
|
## [1.3.0] - 2022-02-22
|
2
10
|
|
3
11
|
- add support of named arguments with `argument <name>`
|
data/README.md
CHANGED
@@ -188,21 +188,25 @@ users.map(&:orders_count) # perform will be used once without N+1
|
|
188
188
|
class User
|
189
189
|
include N1Loader::Loadable
|
190
190
|
|
191
|
-
n1_optimized :orders_count do
|
192
|
-
|
193
|
-
|
194
|
-
|
191
|
+
n1_optimized :orders_count do
|
192
|
+
argument :type
|
193
|
+
|
194
|
+
def perform(users)
|
195
|
+
orders_per_user = Order.where(type: type, user: users).group(:user_id).count
|
196
|
+
|
197
|
+
users.each { |user| fulfill(user, orders_per_user[user.id]) }
|
198
|
+
end
|
195
199
|
end
|
196
200
|
end
|
197
201
|
|
198
202
|
user = User.new
|
199
|
-
user.orders_count(:gifts) # The loader will be performed first time for this argument
|
200
|
-
user.orders_count(:sales) # The loader will be performed first time for this argument
|
201
|
-
user.orders_count(:gifts) # The cached value will be used
|
203
|
+
user.orders_count(type: :gifts) # The loader will be performed first time for this argument
|
204
|
+
user.orders_count(type: :sales) # The loader will be performed first time for this argument
|
205
|
+
user.orders_count(type: :gifts) # The cached value will be used
|
202
206
|
|
203
207
|
users = [User.new, User.new]
|
204
208
|
N1Loader::Preloader.new(users).preload(:orders_count)
|
205
|
-
users.map { |user| user.orders_count(:gifts) } # No N+1 here
|
209
|
+
users.map { |user| user.orders_count(type: :gifts) } # No N+1 here
|
206
210
|
```
|
207
211
|
|
208
212
|
_Note_: By default, we use `arguments.map(&:object_id)` to identify arguments but in some cases,
|
@@ -217,7 +221,7 @@ class User
|
|
217
221
|
|
218
222
|
cache_key { sale.id }
|
219
223
|
|
220
|
-
def perform(users
|
224
|
+
def perform(users)
|
221
225
|
orders_per_user = Order.where(sale: sale, user: users).group(:user_id).count
|
222
226
|
|
223
227
|
users.each { |user| fulfill(user, orders_per_user[user.id]) }
|
@@ -226,8 +230,8 @@ class User
|
|
226
230
|
end
|
227
231
|
|
228
232
|
user = User.new
|
229
|
-
user.orders_count(Sale.first) # perform will be executed and value will be cached
|
230
|
-
user.orders_count(Sale.first) # the cached value will be returned
|
233
|
+
user.orders_count(sale: Sale.first) # perform will be executed and value will be cached
|
234
|
+
user.orders_count(sale: Sale.first) # the cached value will be returned
|
231
235
|
```
|
232
236
|
|
233
237
|
|
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
N1Loader::LoaderCollection.define_method :preloaded_records do
|
4
|
-
|
5
|
-
raise N1Loader::ActiveRecord::InvalidPreloading, "Cannot preload loader with arguments"
|
6
|
-
end
|
4
|
+
raise N1Loader::ActiveRecord::InvalidPreloading, "Cannot preload loader with arguments" if loader_class.arguments
|
7
5
|
|
8
6
|
with.preloaded_records
|
9
7
|
end
|
@@ -47,7 +47,7 @@ module N1Loader
|
|
47
47
|
|
48
48
|
def n1_optimized(name, loader = nil, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
49
49
|
loader ||= Class.new(N1Loader::Loader) do
|
50
|
-
if block
|
50
|
+
if block.arity == 1
|
51
51
|
define_method(:perform, &block)
|
52
52
|
else
|
53
53
|
class_eval(&block)
|
@@ -73,10 +73,10 @@ module N1Loader
|
|
73
73
|
instance_variable_get(loader_variable_name) || send("#{loader_name}_reload")
|
74
74
|
end
|
75
75
|
|
76
|
-
define_method(name) do
|
76
|
+
define_method(name) do |reload: false, **args|
|
77
77
|
send("#{loader_name}_reload") if reload
|
78
78
|
|
79
|
-
send(loader_name).with(
|
79
|
+
send(loader_name).with(**args).for(self)
|
80
80
|
end
|
81
81
|
|
82
82
|
[name, loader_name, loader_variable_name]
|
@@ -13,11 +13,16 @@ module N1Loader
|
|
13
13
|
#
|
14
14
|
# First defined argument will have the value of first passed argument,
|
15
15
|
# meaning the order is important.
|
16
|
-
|
16
|
+
#
|
17
|
+
# @param name [Symbol]
|
18
|
+
# @param opts [Hash]
|
19
|
+
# @option opts [Boolean] optional false by default
|
20
|
+
def argument(name, **opts)
|
17
21
|
@arguments ||= []
|
18
|
-
|
19
|
-
define_method(name) { args[
|
20
|
-
|
22
|
+
|
23
|
+
define_method(name) { args[name] }
|
24
|
+
|
25
|
+
@arguments << opts.merge(name: name)
|
21
26
|
end
|
22
27
|
|
23
28
|
# Defines a custom cache key that is calculated for passed arguments.
|
@@ -29,7 +34,7 @@ module N1Loader
|
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
|
-
def initialize(elements,
|
37
|
+
def initialize(elements, **args)
|
33
38
|
@elements = elements
|
34
39
|
@args = args
|
35
40
|
end
|
@@ -44,18 +49,45 @@ module N1Loader
|
|
44
49
|
end
|
45
50
|
|
46
51
|
def cache_key
|
47
|
-
|
52
|
+
check_arguments!
|
53
|
+
args.values.map(&:object_id)
|
48
54
|
end
|
49
55
|
|
50
56
|
private
|
51
57
|
|
52
58
|
attr_reader :elements, :args
|
53
59
|
|
60
|
+
def check_missing_arguments! # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
61
|
+
return unless (arguments = self.class.arguments)
|
62
|
+
|
63
|
+
min = arguments.count { |argument| !argument[:optional] }
|
64
|
+
max = arguments.count
|
65
|
+
|
66
|
+
return if args.size >= min && args.size <= max
|
67
|
+
|
68
|
+
str =
|
69
|
+
if min == max
|
70
|
+
max.to_s
|
71
|
+
else
|
72
|
+
"#{min}..#{max}"
|
73
|
+
end
|
74
|
+
|
75
|
+
raise MissingArgument, "Loader requires #{str} arguments but #{args.size} were given"
|
76
|
+
end
|
77
|
+
|
54
78
|
def check_arguments!
|
55
|
-
|
56
|
-
|
79
|
+
check_missing_arguments!
|
80
|
+
check_invalid_arguments!
|
81
|
+
end
|
57
82
|
|
58
|
-
|
83
|
+
def check_invalid_arguments!
|
84
|
+
return unless (arguments = self.class.arguments)
|
85
|
+
|
86
|
+
args.each_key do |arg|
|
87
|
+
next if arguments.find { |argument| argument[:name] == arg }
|
88
|
+
|
89
|
+
raise InvalidArgument, "Loader doesn't define #{arg} argument"
|
90
|
+
end
|
59
91
|
end
|
60
92
|
|
61
93
|
def perform(_elements)
|
@@ -66,7 +98,7 @@ module N1Loader
|
|
66
98
|
@loaded[element] = value
|
67
99
|
end
|
68
100
|
|
69
|
-
def loaded
|
101
|
+
def loaded
|
70
102
|
return @loaded if @loaded
|
71
103
|
|
72
104
|
check_arguments!
|
@@ -74,9 +106,9 @@ module N1Loader
|
|
74
106
|
@loaded = {}.compare_by_identity
|
75
107
|
|
76
108
|
if elements.size == 1 && respond_to?(:single)
|
77
|
-
fulfill(elements.first, single(elements.first
|
109
|
+
fulfill(elements.first, single(elements.first))
|
78
110
|
elsif elements.any?
|
79
|
-
perform(elements
|
111
|
+
perform(elements)
|
80
112
|
end
|
81
113
|
|
82
114
|
@loaded
|
data/lib/n1_loader/version.rb
CHANGED
data/lib/n1_loader.rb
CHANGED