n1_loader 0.1.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +7 -0
- data/CHANGELOG.md +8 -2
- data/README.md +137 -14
- data/gemfiles/ar_5_latest.gemfile +7 -0
- data/lib/n1_loader/active_record/associations_preloader_v5.rb +39 -0
- data/lib/n1_loader/active_record/{associations_preloader.rb → associations_preloader_v6.rb} +3 -1
- data/lib/n1_loader/active_record/loader.rb +5 -0
- data/lib/n1_loader/active_record.rb +9 -2
- data/lib/n1_loader/ar_lazy_preload/context_adapter.rb +1 -1
- data/lib/n1_loader/{loadable.rb → core/loadable.rb} +16 -11
- data/lib/n1_loader/{loader.rb → core/loader.rb} +25 -12
- data/lib/n1_loader/{preloader.rb → core/preloader.rb} +0 -0
- data/lib/n1_loader/version.rb +1 -1
- data/lib/n1_loader.rb +4 -3
- data/n1_loader.gemspec +2 -2
- metadata +17 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a365bb6b58a962185cd24033f6dd6cb98510712973dacdea4977a3121b64adc
|
4
|
+
data.tar.gz: d06031503475dc13f52acddb881931de5b7dd244acab6b46553d4a73c8efbd2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9172c4cd233739a0ebc379b3988037349d028020d5eb066642532f2b3da2a75d3faa34edd872aa5b5925eed91509c2c3a202e7a9aa448ca5020435b4f5e9c5a5
|
7
|
+
data.tar.gz: e74f92e69f47909b812adecb1aa7dc319c090a2ad865e89732a4ebdbbd378c02dbec28cc7ff5b0ff42262acf3a07e8deb8a4a949634d70c6d6c3986837a6ab5d
|
data/.circleci/config.yml
CHANGED
@@ -86,8 +86,15 @@ workflows:
|
|
86
86
|
"latest"
|
87
87
|
]
|
88
88
|
gemfile: [
|
89
|
+
"gemfiles/ar_5_latest.gemfile",
|
89
90
|
"gemfiles/ar_6_latest.gemfile"
|
90
91
|
]
|
92
|
+
exclude:
|
93
|
+
- ruby-version: "3.0"
|
94
|
+
gemfile: "gemfiles/ar_5_latest.gemfile"
|
95
|
+
- ruby-version: "latest"
|
96
|
+
gemfile: "gemfiles/ar_5_latest.gemfile"
|
97
|
+
|
91
98
|
name: << matrix.gemfile >>-build-ruby-<< matrix.ruby-version >>
|
92
99
|
- rubocop:
|
93
100
|
requires:
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -4,14 +4,20 @@
|
|
4
4
|
[![Gem Version][3]][4]
|
5
5
|
|
6
6
|
Are you tired of fixing [N+1 issues][7]? Does it feel unnatural to you to fix it case by case in places where you need the data?
|
7
|
-
We have a solution for you!
|
7
|
+
We have a solution for you!
|
8
|
+
|
9
|
+
[N1Loader][8] is designed to solve the issue for good!
|
8
10
|
|
9
11
|
It has many benefits:
|
10
|
-
- it
|
11
|
-
- it
|
12
|
+
- it can be [isolated](#isolated-loaders)
|
13
|
+
- it loads data [lazily](#lazy-loading)
|
14
|
+
- it supports [shareable loaders](#shareable-loaders) between multiple classes
|
15
|
+
- it supports [reloading](#reloading)
|
16
|
+
- it supports optimized [single object loading](#optimized-single-case)
|
12
17
|
- it has an integration with [ActiveRecord][5] which makes it brilliant ([example](#activerecord))
|
13
18
|
- it has an integration with [ArLazyPreload][6] which makes it excellent ([example](#arlazypreload))
|
14
19
|
|
20
|
+
... and even more features to come! Stay tuned!
|
15
21
|
|
16
22
|
## Installation
|
17
23
|
|
@@ -23,24 +29,25 @@ gem 'n1_loader'
|
|
23
29
|
|
24
30
|
You can add integration with [ActiveRecord][5] by:
|
25
31
|
```ruby
|
26
|
-
require 'n1_loader/active_record'
|
32
|
+
gem 'n1_loader', require: 'n1_loader/active_record'
|
27
33
|
```
|
28
34
|
|
29
35
|
You can add the integration with [ActiveRecord][5] and [ArLazyPreload][6] by:
|
30
36
|
```ruby
|
31
|
-
require 'n1_loader/ar_lazy_preload'
|
37
|
+
gem 'n1_loader', require: 'n1_loader/ar_lazy_preload'
|
32
38
|
```
|
33
39
|
|
34
40
|
## Usage
|
35
41
|
|
42
|
+
**Supported Ruby version:** 2.5, 2.6, 2.7, 3.0, and latest.
|
43
|
+
|
36
44
|
```ruby
|
37
45
|
class Example
|
38
46
|
include N1Loader::Loadable
|
39
47
|
|
40
48
|
# with inline loader
|
41
49
|
n1_loader :anything do |elements|
|
42
|
-
|
43
|
-
elements.group_by(&:itself)
|
50
|
+
elements.each { |element| fulfill(element, [element]) }
|
44
51
|
end
|
45
52
|
|
46
53
|
# with custom loader
|
@@ -49,9 +56,8 @@ end
|
|
49
56
|
|
50
57
|
# Custom loader that can be shared with many classes
|
51
58
|
class MyLoader < N1Loader::Loader
|
52
|
-
# Has to return a hash that has keys as element from elements
|
53
59
|
def perform(elements)
|
54
|
-
elements.
|
60
|
+
elements.each { |element| fulfill(element, [element]) }
|
55
61
|
end
|
56
62
|
end
|
57
63
|
|
@@ -65,8 +71,127 @@ N1Loader::Preloader.new(objects).preload(:anything)
|
|
65
71
|
objects.map(&:anything)
|
66
72
|
```
|
67
73
|
|
74
|
+
### Lazy loading
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
class Example
|
78
|
+
include N1Loader::Loadable
|
79
|
+
|
80
|
+
n1_loader :anything do |elements|
|
81
|
+
elements.each { |element| fulfill(element, [element]) }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
object = Example.new # => nothing was done for loading
|
86
|
+
object.anything # => first time loading
|
87
|
+
|
88
|
+
objects = [Example.new, Example.new] # => nothing was done for loading
|
89
|
+
N1Loader::Preloader.new([objects]).preload(:anything) # => we only initial loader but didn't perform it yet
|
90
|
+
objects.map(&:anything) # => loading happen for the first time (without N+1)
|
91
|
+
```
|
92
|
+
|
93
|
+
|
94
|
+
### Shareable loaders
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
class MyLoader < N1Loader::Loader
|
98
|
+
def perform(elements)
|
99
|
+
elements.each { |element| fulfill(element, [element]) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class A
|
104
|
+
include N1Loader::Loadable
|
105
|
+
|
106
|
+
n1_loader :anything, MyLoader
|
107
|
+
end
|
108
|
+
|
109
|
+
class B
|
110
|
+
include N1Loader::Loadable
|
111
|
+
|
112
|
+
n1_loader :something, MyLoader
|
113
|
+
end
|
114
|
+
|
115
|
+
A.new.anything # => works
|
116
|
+
B.new.something # => works
|
117
|
+
```
|
118
|
+
|
119
|
+
### Reloading
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
class Example
|
123
|
+
include N1Loader::Loadable
|
124
|
+
|
125
|
+
# with inline loader
|
126
|
+
n1_loader :anything do |elements|
|
127
|
+
elements.each { |element| fulfill(element, [element]) }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
object = Example.new
|
132
|
+
object.anything # => loader is executed first time and value was cached
|
133
|
+
object.anything(reload: true) # => loader is executed again and a new value was cached
|
134
|
+
|
135
|
+
objects = [Example.new, Example.new]
|
136
|
+
|
137
|
+
N1Loader::Preloader.new(objects).preload(:anything) # => loader was initialized but not yet executed
|
138
|
+
objects.map(&:anything) # => loader was executed first time without N+1 issue and values were cached
|
139
|
+
|
140
|
+
N1Loader::Preloader.new(objects).preload(:anything) # => loader was initialized again but not yet executed
|
141
|
+
objects.map(&:anything) # => new loader was executed first time without N+1 issue and new values were cached
|
142
|
+
```
|
143
|
+
|
144
|
+
### Isolated loaders
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
class MyLoader < N1Loader::Loader
|
148
|
+
def perform(elements)
|
149
|
+
elements.each { |element| fulfill(element, [element]) }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
objects = [1, 2, 3, 4]
|
154
|
+
loader = MyLoader.new(objects)
|
155
|
+
objects.each do |object|
|
156
|
+
loader.for(object) # => it has no N+1 and it doesn't require to be injected in the class
|
157
|
+
end
|
158
|
+
```
|
159
|
+
|
160
|
+
### Optimized single case
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
class Example
|
164
|
+
include N1Loader::Loadable
|
165
|
+
|
166
|
+
n1_loader :something do # no arguments passed to the block, so we can override both perform and single.
|
167
|
+
def perform(elements)
|
168
|
+
elements.each { |element| fulfill(element, [element]) }
|
169
|
+
end
|
170
|
+
|
171
|
+
# Optimized for single object loading
|
172
|
+
def single(element)
|
173
|
+
# Just return a value you want to have for this element
|
174
|
+
[element]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
object = Example.new
|
180
|
+
object.something # single will be used here
|
181
|
+
|
182
|
+
objects = [Example.new, Example.new]
|
183
|
+
N1Loader::Preloader.new(objects).preload(:something)
|
184
|
+
objects.map(&:something) # perform will be used once without N+1
|
185
|
+
```
|
186
|
+
|
187
|
+
## Integrations
|
188
|
+
|
68
189
|
### [ActiveRecord][5]
|
69
190
|
|
191
|
+
**Supported versions**: 5, 6.
|
192
|
+
|
193
|
+
_Note_: Please open an issue if you interested in support of version 7 or other.
|
194
|
+
|
70
195
|
```ruby
|
71
196
|
class User < ActiveRecord::Base
|
72
197
|
include N1Loader::Loadable
|
@@ -74,8 +199,7 @@ class User < ActiveRecord::Base
|
|
74
199
|
n1_loader :orders_count do |users|
|
75
200
|
hash = Order.where(user: users).group(:user_id).count
|
76
201
|
|
77
|
-
|
78
|
-
hash.transform_keys! { |key| users.find { |user| user.id == key } }
|
202
|
+
users.each { |user| fulfill(user, hash[user.id]) }
|
79
203
|
end
|
80
204
|
end
|
81
205
|
|
@@ -102,9 +226,8 @@ class User < ActiveRecord::Base
|
|
102
226
|
|
103
227
|
n1_loader :orders_count do |users|
|
104
228
|
hash = Order.where(user: users).group(:user_id).count
|
105
|
-
|
106
|
-
|
107
|
-
hash.transform_keys! { |key| users.find { |user| user.id == key } }
|
229
|
+
|
230
|
+
users.each { |user| fulfill(user, hash[user.id]) }
|
108
231
|
end
|
109
232
|
end
|
110
233
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module N1Loader
|
4
|
+
module ActiveRecord
|
5
|
+
module Associations
|
6
|
+
module Preloader # :nodoc:
|
7
|
+
N1LoaderReflection = Struct.new(:key, :loader) do
|
8
|
+
def options
|
9
|
+
{}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def preloaders_for_one(association, records, scope)
|
14
|
+
grouped_records(association, records).flat_map do |reflection, klasses|
|
15
|
+
next N1Loader::Preloader.new(records).preload(reflection.key) if reflection.is_a?(N1LoaderReflection)
|
16
|
+
|
17
|
+
klasses.map do |rhs_klass, rs|
|
18
|
+
loader = preloader_for(reflection, rs).new(rhs_klass, rs, reflection, scope)
|
19
|
+
loader.run self
|
20
|
+
loader
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def grouped_records(association, records)
|
26
|
+
n1_load_records, records = records.partition do |record|
|
27
|
+
record.class.respond_to?(:n1_loader_defined?) && record.class.n1_loader_defined?(association)
|
28
|
+
end
|
29
|
+
|
30
|
+
hash = n1_load_records.group_by do |record|
|
31
|
+
N1LoaderReflection.new(association, record.class.n1_loader(association))
|
32
|
+
end
|
33
|
+
|
34
|
+
hash.merge(super)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -17,7 +17,9 @@ module N1Loader
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def grouped_records(association, records, polymorphic_parent)
|
20
|
-
n1_load_records, records = records.partition
|
20
|
+
n1_load_records, records = records.partition do |record|
|
21
|
+
record.class.respond_to?(:n1_loader_defined?) && record.class.n1_loader_defined?(association)
|
22
|
+
end
|
21
23
|
|
22
24
|
hash = n1_load_records.group_by do |record|
|
23
25
|
N1LoaderReflection.new(association, record.class.n1_loader(association))
|
@@ -1,9 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "../n1_loader"
|
4
|
+
require_relative "active_record/loader"
|
3
5
|
require "active_record"
|
4
6
|
|
5
|
-
require_relative "active_record/associations_preloader"
|
6
|
-
|
7
7
|
ActiveSupport.on_load(:active_record) do
|
8
|
+
case ActiveRecord::VERSION::MAJOR
|
9
|
+
when 6
|
10
|
+
require_relative "active_record/associations_preloader_v6"
|
11
|
+
else
|
12
|
+
require_relative "active_record/associations_preloader_v5"
|
13
|
+
end
|
14
|
+
|
8
15
|
ActiveRecord::Associations::Preloader.prepend(N1Loader::ActiveRecord::Associations::Preloader)
|
9
16
|
end
|
@@ -8,9 +8,7 @@ module N1Loader
|
|
8
8
|
#
|
9
9
|
# # with inline loader
|
10
10
|
# n1_loader :something do |elements|
|
11
|
-
# elements.
|
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.
|
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
|
@@ -47,9 +43,13 @@ module N1Loader
|
|
47
43
|
respond_to?("#{name}_loader")
|
48
44
|
end
|
49
45
|
|
50
|
-
def n1_load(name, loader = nil, &block) # rubocop:disable Metrics/MethodLength
|
46
|
+
def n1_load(name, loader = nil, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
51
47
|
loader ||= Class.new(N1Loader::Loader) do
|
52
|
-
|
48
|
+
if block && block.arity == 1
|
49
|
+
define_method(:perform, &block)
|
50
|
+
else
|
51
|
+
class_eval(&block)
|
52
|
+
end
|
53
53
|
end
|
54
54
|
|
55
55
|
loader_name = "#{name}_loader"
|
@@ -59,16 +59,21 @@ module N1Loader
|
|
59
59
|
loader
|
60
60
|
end
|
61
61
|
|
62
|
+
define_method("#{loader_name}_reload") do
|
63
|
+
instance_variable_set(loader_variable_name, self.class.send(loader_name).new([self]))
|
64
|
+
end
|
65
|
+
|
62
66
|
define_method("#{loader_name}=") do |loader_instance|
|
63
67
|
instance_variable_set(loader_variable_name, loader_instance)
|
64
68
|
end
|
65
69
|
|
66
70
|
define_method(loader_name) do
|
67
|
-
instance_variable_get(loader_variable_name) ||
|
68
|
-
instance_variable_set(loader_variable_name, self.class.send(loader_name).new([self]))
|
71
|
+
instance_variable_get(loader_variable_name) || send("#{loader_name}_reload")
|
69
72
|
end
|
70
73
|
|
71
|
-
define_method(name) do
|
74
|
+
define_method(name) do |reload: false|
|
75
|
+
send("#{loader_name}_reload") if reload
|
76
|
+
|
72
77
|
send(loader_name).for(self)
|
73
78
|
end
|
74
79
|
|
@@ -10,26 +10,39 @@ module N1Loader
|
|
10
10
|
@elements = elements
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
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
|
-
|
18
|
-
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :elements
|
25
|
+
|
26
|
+
def perform(_elements)
|
27
|
+
raise NotImplemented, "Subclasses have to implement the method"
|
19
28
|
end
|
20
29
|
|
21
|
-
def
|
22
|
-
@
|
30
|
+
def fulfill(element, value)
|
31
|
+
@loaded[element] = value
|
23
32
|
end
|
24
33
|
|
25
|
-
def
|
26
|
-
|
34
|
+
def loaded
|
35
|
+
return @loaded if @loaded
|
27
36
|
|
28
|
-
loaded.compare_by_identity
|
29
|
-
end
|
37
|
+
@loaded = {}.compare_by_identity
|
30
38
|
|
31
|
-
|
39
|
+
if elements.size == 1 && respond_to?(:single)
|
40
|
+
fulfill(elements.first, single(elements.first))
|
41
|
+
elsif elements.any?
|
42
|
+
perform(elements)
|
43
|
+
end
|
32
44
|
|
33
|
-
|
45
|
+
@loaded
|
46
|
+
end
|
34
47
|
end
|
35
48
|
end
|
File without changes
|
data/lib/n1_loader/version.rb
CHANGED
data/lib/n1_loader.rb
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative "n1_loader/version"
|
4
4
|
|
5
|
-
require_relative "n1_loader/loader"
|
6
|
-
require_relative "n1_loader/loadable"
|
7
|
-
require_relative "n1_loader/preloader"
|
5
|
+
require_relative "n1_loader/core/loader"
|
6
|
+
require_relative "n1_loader/core/loadable"
|
7
|
+
require_relative "n1_loader/core/preloader"
|
8
8
|
|
9
9
|
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
|
data/n1_loader.gemspec
CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
end
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_development_dependency "activerecord", "
|
25
|
+
spec.add_development_dependency "activerecord", ">= 5"
|
26
26
|
spec.add_development_dependency "ar_lazy_preload", "~> 0.7"
|
27
27
|
spec.add_development_dependency "db-query-matchers", "~> 0.10"
|
28
|
-
spec.add_development_dependency "rails", "
|
28
|
+
spec.add_development_dependency "rails", ">= 5"
|
29
29
|
spec.add_development_dependency "rspec", "~> 3.0"
|
30
30
|
spec.add_development_dependency "rspec_junit_formatter", "~> 0.4"
|
31
31
|
spec.add_development_dependency "rubocop", "~> 1.7"
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: n1_loader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
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-
|
11
|
+
date: 2021-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ar_lazy_preload
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: rails
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '5'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '5'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,17 +141,20 @@ files:
|
|
141
141
|
- Rakefile
|
142
142
|
- bin/console
|
143
143
|
- bin/setup
|
144
|
+
- gemfiles/ar_5_latest.gemfile
|
144
145
|
- gemfiles/ar_6_latest.gemfile
|
145
146
|
- lib/n1_loader.rb
|
146
147
|
- lib/n1_loader/active_record.rb
|
147
|
-
- lib/n1_loader/active_record/
|
148
|
+
- lib/n1_loader/active_record/associations_preloader_v5.rb
|
149
|
+
- lib/n1_loader/active_record/associations_preloader_v6.rb
|
150
|
+
- lib/n1_loader/active_record/loader.rb
|
148
151
|
- lib/n1_loader/ar_lazy_preload.rb
|
149
152
|
- lib/n1_loader/ar_lazy_preload/associated_context_builder.rb
|
150
153
|
- lib/n1_loader/ar_lazy_preload/context_adapter.rb
|
151
154
|
- lib/n1_loader/ar_lazy_preload/loadable.rb
|
152
|
-
- lib/n1_loader/loadable.rb
|
153
|
-
- lib/n1_loader/loader.rb
|
154
|
-
- lib/n1_loader/preloader.rb
|
155
|
+
- lib/n1_loader/core/loadable.rb
|
156
|
+
- lib/n1_loader/core/loader.rb
|
157
|
+
- lib/n1_loader/core/preloader.rb
|
155
158
|
- lib/n1_loader/version.rb
|
156
159
|
- n1_loader.gemspec
|
157
160
|
homepage: https://github.com/djezzzl/n1_loader
|