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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bca887aa87a283d55ee26b1fe606948733ecfecc7ce40d4cedc8b89d90efb834
4
- data.tar.gz: 9a7c463ccacf8daeebc23d2eaa375d8c4f908b333c492baaa4c4c931bbc7d1b3
3
+ metadata.gz: 11ad98c8ab59226bb807d9686a0440140b7ca802d2faf33a0c26c428f2371e7a
4
+ data.tar.gz: 0e4832fbea9fc6fafce7445390ef34eed82c3984df471486a7e871db4c6b2717
5
5
  SHA512:
6
- metadata.gz: 30920baa0426de8bc5188fc80ccfacf6e040f6bf1f7c934214bb75600080a090756ca957da9a59327a63b30550d7a4efdf5f4e66c873783e0c5aa627fe558e9f
7
- data.tar.gz: 9adfa72af9bfcc684c3c22f6e82b353af9b36081224cae92e248e5c52db7f028a9c6f49dc3760d059f476980a48f4852b6f94c5e5faf82dbef28087e0b8dd3cd
6
+ metadata.gz: c8932fc1d40b83fd0678ceed57856ab13021e047e9c4ea82b6b42434b98b760f9d51d5b77b232db249573bce512e930e7374b006e09977d9105086a24ff79b1b
7
+ data.tar.gz: 9595ae9cddddde356275480f54efe19c3792e93b100abad3ddced491644c06d8dfc197af4651a7be7af9aa1fe4d319fcf8f383e6493f2e7efec245094926e56e
@@ -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: 2.7
25
+ ruby-version: 3.1
28
26
  - name: Install dependencies
29
27
  run: bundle install
30
28
  - name: Run tests
@@ -13,10 +13,10 @@ jobs:
13
13
 
14
14
  steps:
15
15
  - uses: actions/checkout@v4
16
- - name: Set up Ruby 2.7
16
+ - name: Set up Ruby 3.1
17
17
  uses: ruby/setup-ruby@v1
18
18
  with:
19
- ruby-version: 2.7
19
+ ruby-version: 3.1
20
20
 
21
21
  - name: Publish to RubyGems
22
22
  env:
data/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem "activerecord", ">=7"
4
+ gem "sqlite3", "~> 1.4"
4
5
  # Specify your gem's dependencies in jit_preloader.gemspec
5
6
  gemspec
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module JitPreloader
2
- VERSION = "2.1.0"
2
+ VERSION = "3.0.0"
3
3
  end
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.0.0")
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: 2.1.0
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-04-29 00:00:00.000000000 Z
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.1.6
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
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem "activerecord", "~>5.2"
4
-
5
- # Specify your gem's dependencies in jit_preloader.gemspec
6
- gemspec
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)