jit_preloader 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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)