n1_loader 0.1.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 +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
|