jit_preloader 2.1.0 → 3.0.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/.github/workflows/ci.yml +1 -3
- data/.github/workflows/gem-push.yml +2 -2
- data/Gemfile +1 -0
- data/lib/jit_preloader/active_record/associations/singular_association.rb +5 -1
- data/lib/jit_preloader/version.rb +1 -1
- data/lib/jit_preloader.rb +1 -3
- data/spec/lib/jit_preloader/preloader_spec.rb +24 -0
- metadata +3 -6
- data/Gemfile.5.2 +0 -6
- data/Gemfile.5.2.lock +0 -72
- data/lib/jit_preloader/active_record/associations/preloader/ar5_association.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11ad98c8ab59226bb807d9686a0440140b7ca802d2faf33a0c26c428f2371e7a
|
4
|
+
data.tar.gz: 0e4832fbea9fc6fafce7445390ef34eed82c3984df471486a7e871db4c6b2717
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8932fc1d40b83fd0678ceed57856ab13021e047e9c4ea82b6b42434b98b760f9d51d5b77b232db249573bce512e930e7374b006e09977d9105086a24ff79b1b
|
7
|
+
data.tar.gz: 9595ae9cddddde356275480f54efe19c3792e93b100abad3ddced491644c06d8dfc197af4651a7be7af9aa1fe4d319fcf8f383e6493f2e7efec245094926e56e
|
data/.github/workflows/ci.yml
CHANGED
@@ -14,8 +14,6 @@ jobs:
|
|
14
14
|
matrix:
|
15
15
|
gemfile:
|
16
16
|
- Gemfile
|
17
|
-
- Gemfile.5.2
|
18
|
-
- Gemfile.6.0
|
19
17
|
- Gemfile.6.1
|
20
18
|
env:
|
21
19
|
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
@@ -24,7 +22,7 @@ jobs:
|
|
24
22
|
- name: Set up Ruby ${{ matrix.ruby-version }}
|
25
23
|
uses: ruby/setup-ruby@v1
|
26
24
|
with:
|
27
|
-
ruby-version:
|
25
|
+
ruby-version: 3.1
|
28
26
|
- name: Install dependencies
|
29
27
|
run: bundle install
|
30
28
|
- name: Run tests
|
data/Gemfile
CHANGED
@@ -18,13 +18,17 @@ module JitPreloader
|
|
18
18
|
# always an N+1 query.
|
19
19
|
record.jit_n_plus_one_tracking ||= owner.jit_n_plus_one_tracking if record
|
20
20
|
|
21
|
-
if !jit_loaded && owner.jit_n_plus_one_tracking
|
21
|
+
if !jit_loaded && owner.jit_n_plus_one_tracking && !is_polymorphic_association_without_type
|
22
22
|
ActiveSupport::Notifications.publish("n_plus_one_query",
|
23
23
|
source: owner, association: reflection.name)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
|
+
|
29
|
+
private def is_polymorphic_association_without_type
|
30
|
+
self.is_a?(ActiveRecord::Associations::BelongsToPolymorphicAssociation) && self.klass.nil?
|
31
|
+
end
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
data/lib/jit_preloader.rb
CHANGED
@@ -11,10 +11,8 @@ require 'jit_preloader/active_record/associations/singular_association'
|
|
11
11
|
if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("7.0.0")
|
12
12
|
require 'jit_preloader/active_record/associations/preloader/ar7_association'
|
13
13
|
require 'jit_preloader/active_record/associations/preloader/ar7_branch'
|
14
|
-
elsif Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("6.
|
14
|
+
elsif Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("6.1.0")
|
15
15
|
require 'jit_preloader/active_record/associations/preloader/ar6_association'
|
16
|
-
elsif Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("5.2.2")
|
17
|
-
require 'jit_preloader/active_record/associations/preloader/ar5_association'
|
18
16
|
else
|
19
17
|
require 'jit_preloader/active_record/associations/preloader/collection_association'
|
20
18
|
require 'jit_preloader/active_record/associations/preloader/singular_association'
|
@@ -165,6 +165,30 @@ RSpec.describe JitPreloader::Preloader do
|
|
165
165
|
expect(Contact.jit_preload.map(&:contact_owner)).to eq [nil, ContactOwner.first, Address.first]
|
166
166
|
end
|
167
167
|
end
|
168
|
+
|
169
|
+
context "when a record has a polymorphic association type is nil" do
|
170
|
+
before do
|
171
|
+
contact1.update!(contact_owner_type: nil, contact_owner_id: nil)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "successfully load the rest of association values and does not publish a n+1 notification" do
|
175
|
+
contacts = Contact.jit_preload.to_a
|
176
|
+
ActiveSupport::Notifications.subscribed(callback, "n_plus_one_query") do
|
177
|
+
expect(contacts.first.contact_owner).to eq(nil)
|
178
|
+
end
|
179
|
+
|
180
|
+
expect(source_map).to eql({})
|
181
|
+
|
182
|
+
expect do
|
183
|
+
contacts.first.contact_owner
|
184
|
+
contacts.second.contact_owner
|
185
|
+
contacts.third.contact_owner
|
186
|
+
end.not_to make_database_queries
|
187
|
+
|
188
|
+
expect(contacts.second.contact_owner).to eq(ContactOwner.first)
|
189
|
+
expect(contacts.third.contact_owner).to eq(Address.first)
|
190
|
+
end
|
191
|
+
end
|
168
192
|
end
|
169
193
|
end
|
170
194
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jit_preloader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle d'Oliveira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -151,8 +151,6 @@ files:
|
|
151
151
|
- ".gitignore"
|
152
152
|
- ".rspec"
|
153
153
|
- Gemfile
|
154
|
-
- Gemfile.5.2
|
155
|
-
- Gemfile.5.2.lock
|
156
154
|
- Gemfile.6.0
|
157
155
|
- Gemfile.6.0.lock
|
158
156
|
- Gemfile.6.1
|
@@ -163,7 +161,6 @@ files:
|
|
163
161
|
- jit_preloader.gemspec
|
164
162
|
- lib/jit_preloader.rb
|
165
163
|
- lib/jit_preloader/active_record/associations/collection_association.rb
|
166
|
-
- lib/jit_preloader/active_record/associations/preloader/ar5_association.rb
|
167
164
|
- lib/jit_preloader/active_record/associations/preloader/ar6_association.rb
|
168
165
|
- lib/jit_preloader/active_record/associations/preloader/ar7_association.rb
|
169
166
|
- lib/jit_preloader/active_record/associations/preloader/ar7_branch.rb
|
@@ -198,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
198
195
|
- !ruby/object:Gem::Version
|
199
196
|
version: '0'
|
200
197
|
requirements: []
|
201
|
-
rubygems_version: 3.
|
198
|
+
rubygems_version: 3.3.27
|
202
199
|
signing_key:
|
203
200
|
specification_version: 4
|
204
201
|
summary: Tool to understand N+1 queries and to remove them
|
data/Gemfile.5.2
DELETED
data/Gemfile.5.2.lock
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
jit_preloader (1.0.3)
|
5
|
-
activerecord (>= 5.2, < 7)
|
6
|
-
activesupport
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
activemodel (5.2.6)
|
12
|
-
activesupport (= 5.2.6)
|
13
|
-
activerecord (5.2.6)
|
14
|
-
activemodel (= 5.2.6)
|
15
|
-
activesupport (= 5.2.6)
|
16
|
-
arel (>= 9.0)
|
17
|
-
activesupport (5.2.6)
|
18
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
19
|
-
i18n (>= 0.7, < 2)
|
20
|
-
minitest (~> 5.1)
|
21
|
-
tzinfo (~> 1.1)
|
22
|
-
arel (9.0.0)
|
23
|
-
byebug (11.1.3)
|
24
|
-
concurrent-ruby (1.1.9)
|
25
|
-
database_cleaner (2.0.1)
|
26
|
-
database_cleaner-active_record (~> 2.0.0)
|
27
|
-
database_cleaner-active_record (2.0.1)
|
28
|
-
activerecord (>= 5.a)
|
29
|
-
database_cleaner-core (~> 2.0.0)
|
30
|
-
database_cleaner-core (2.0.1)
|
31
|
-
db-query-matchers (0.10.0)
|
32
|
-
activesupport (>= 4.0, < 7)
|
33
|
-
rspec (~> 3.0)
|
34
|
-
diff-lcs (1.4.4)
|
35
|
-
i18n (1.8.10)
|
36
|
-
concurrent-ruby (~> 1.0)
|
37
|
-
minitest (5.14.4)
|
38
|
-
rake (13.0.6)
|
39
|
-
rspec (3.10.0)
|
40
|
-
rspec-core (~> 3.10.0)
|
41
|
-
rspec-expectations (~> 3.10.0)
|
42
|
-
rspec-mocks (~> 3.10.0)
|
43
|
-
rspec-core (3.10.1)
|
44
|
-
rspec-support (~> 3.10.0)
|
45
|
-
rspec-expectations (3.10.1)
|
46
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
47
|
-
rspec-support (~> 3.10.0)
|
48
|
-
rspec-mocks (3.10.2)
|
49
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
50
|
-
rspec-support (~> 3.10.0)
|
51
|
-
rspec-support (3.10.2)
|
52
|
-
sqlite3 (1.4.2)
|
53
|
-
thread_safe (0.3.6)
|
54
|
-
tzinfo (1.2.9)
|
55
|
-
thread_safe (~> 0.1)
|
56
|
-
|
57
|
-
PLATFORMS
|
58
|
-
x86_64-darwin-19
|
59
|
-
|
60
|
-
DEPENDENCIES
|
61
|
-
activerecord (~> 5.2)
|
62
|
-
bundler
|
63
|
-
byebug
|
64
|
-
database_cleaner
|
65
|
-
db-query-matchers
|
66
|
-
jit_preloader!
|
67
|
-
rake (~> 13.0)
|
68
|
-
rspec
|
69
|
-
sqlite3
|
70
|
-
|
71
|
-
BUNDLED WITH
|
72
|
-
2.2.12
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module JitPreloader
|
2
|
-
module PreloaderAssociation
|
3
|
-
|
4
|
-
# A monkey patch to ActiveRecord. The old method looked like the snippet
|
5
|
-
# below. Our changes here are that we remove records that are already
|
6
|
-
# part of the target, then attach all of the records to a new jit preloader.
|
7
|
-
#
|
8
|
-
# def run(preloader)
|
9
|
-
# records = load_records do |record|
|
10
|
-
# owner = owners_by_key[convert_key(record[association_key_name])]
|
11
|
-
# association = owner.association(reflection.name)
|
12
|
-
# association.set_inverse_instance(record)
|
13
|
-
# end
|
14
|
-
|
15
|
-
# owners.each do |owner|
|
16
|
-
# associate_records_to_owner(owner, records[convert_key(owner[owner_key_name])] || [])
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
|
20
|
-
def run(preloader)
|
21
|
-
return unless (reflection.scope.nil? || reflection.scope.arity == 0) && klass.ancestors.include?(ActiveRecord::Base)
|
22
|
-
|
23
|
-
super.tap do
|
24
|
-
if preloaded_records.any? && preloaded_records.none?(&:jit_preloader)
|
25
|
-
JitPreloader::Preloader.attach(preloaded_records) if owners.any?(&:jit_preloader) || JitPreloader.globally_enabled?
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Original method:
|
31
|
-
# def associate_records_to_owner(owner, records)
|
32
|
-
# association = owner.association(reflection.name)
|
33
|
-
# association.loaded!
|
34
|
-
# if reflection.collection?
|
35
|
-
# association.target.concat(records)
|
36
|
-
# else
|
37
|
-
# association.target = records.first unless records.empty?
|
38
|
-
# end
|
39
|
-
# end
|
40
|
-
def associate_records_to_owner(owner, records)
|
41
|
-
association = owner.association(reflection.name)
|
42
|
-
association.loaded!
|
43
|
-
|
44
|
-
if reflection.collection?
|
45
|
-
# It is possible that some of the records are loaded already.
|
46
|
-
# We don't want to duplicate them, but we also want to preserve
|
47
|
-
# the original copy so that we don't blow away in-memory changes.
|
48
|
-
new_records = association.target.any? ? records - association.target : records
|
49
|
-
association.target.concat(new_records)
|
50
|
-
association.loaded!
|
51
|
-
else
|
52
|
-
association.target = records.first unless records.empty?
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
|
57
|
-
def build_scope
|
58
|
-
super.tap do |scope|
|
59
|
-
scope.jit_preload! if owners.any?(&:jit_preloader) || JitPreloader.globally_enabled?
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
ActiveRecord::Associations::Preloader::Association.prepend(JitPreloader::PreloaderAssociation)
|
66
|
-
ActiveRecord::Associations::Preloader::ThroughAssociation.prepend(JitPreloader::PreloaderAssociation)
|