jit_preloader 2.0.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: '08fbd77fdcfc580733fbb24995cd80a1535bada8471f2dace6620ad000c25778'
4
- data.tar.gz: bfb07a3212433bc5dd2a5a557ed05d0472f0ec227593a798a1b9442976815d57
3
+ metadata.gz: 11ad98c8ab59226bb807d9686a0440140b7ca802d2faf33a0c26c428f2371e7a
4
+ data.tar.gz: 0e4832fbea9fc6fafce7445390ef34eed82c3984df471486a7e871db4c6b2717
5
5
  SHA512:
6
- metadata.gz: c7fe821295fc841a48992f4fa93bbc372516509435a49455bf9e37543173fe089714198eaa9f0c355cf656d5c2696160c4c82bd657fad79edb9961d5e13e49c7
7
- data.tar.gz: 33ae22de3c658a714be7b5c61705dcb82bdc1d762af3ee0d4ed084d29c6c9e8b6685fa3a353756f653c3287806d1eb946beb95df532983ce85536a82a8fab7fa
6
+ metadata.gz: c8932fc1d40b83fd0678ceed57856ab13021e047e9c4ea82b6b42434b98b760f9d51d5b77b232db249573bce512e930e7374b006e09977d9105086a24ff79b1b
7
+ data.tar.gz: 9595ae9cddddde356275480f54efe19c3792e93b100abad3ddced491644c06d8dfc197af4651a7be7af9aa1fe4d319fcf8f383e6493f2e7efec245094926e56e
@@ -0,0 +1,30 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ gemfile:
16
+ - Gemfile
17
+ - Gemfile.6.1
18
+ env:
19
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - name: Set up Ruby ${{ matrix.ruby-version }}
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: 3.1
26
+ - name: Install dependencies
27
+ run: bundle install
28
+ - name: Run tests
29
+ run:
30
+ bundle exec rspec
@@ -12,11 +12,11 @@ jobs:
12
12
  contents: read
13
13
 
14
14
  steps:
15
- - uses: actions/checkout@v2
16
- - name: Set up Ruby 2.7
17
- uses: actions/setup-ruby@v1
15
+ - uses: actions/checkout@v4
16
+ - name: Set up Ruby 3.1
17
+ uses: ruby/setup-ruby@v1
18
18
  with:
19
- ruby-version: 2.7.x
19
+ ruby-version: 3.1
20
20
 
21
21
  - name: Publish to RubyGems
22
22
  env:
data/.gitignore CHANGED
@@ -10,6 +10,7 @@
10
10
  /test/tmp/
11
11
  /test/version_tmp/
12
12
  /tmp/
13
+ .idea/*
13
14
 
14
15
  # Used by dotenv library to load environment variables.
15
16
  # .env
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem "activerecord", ">=7"
4
+ gem "sqlite3", "~> 1.4"
3
5
  # Specify your gem's dependencies in jit_preloader.gemspec
4
6
  gemspec
data/README.md CHANGED
@@ -173,6 +173,20 @@ end
173
173
 
174
174
  ```
175
175
 
176
+ Furthermore, there is an argument `max_ids_per_query` setting max ids per query. This helps prevent running a single query with too large list of ids which may be less efficient than splitting into multiple queries.
177
+ ```ruby
178
+ class Contact < ActiveRecord::Base
179
+ has_many :addresses
180
+ has_many_aggregate :addresses, :count_all, :count, "*", max_ids_per_query: 10
181
+ end
182
+
183
+ Contact.jit_preload.each do |contact|
184
+ contact.addresses_count_all
185
+ end
186
+ # SELECT contact_id, COUNT(*) FROM addresses WHERE contact_id IN (1, 2, 3, ... ,10) GROUP BY contact_id
187
+ # SELECT contact_id, COUNT(*) FROM addresses WHERE contact_id IN (11, 12, 13) GROUP BY contact_id
188
+ ```
189
+
176
190
  ### Preloading a subset of an association
177
191
 
178
192
  There are often times when you want to preload a subset of an association, or change how the SQL statement is generated. For example, if a `Contact` model has
@@ -213,6 +227,7 @@ end
213
227
  ### Jit preloading globally across your application
214
228
 
215
229
  The JitPreloader can be globally enabled, in which case most N+1 queries in your app should just disappear. It is off by default.
230
+ The `max_ids_per_query` argument on loading aggregate methods can also apply on a global level.
216
231
 
217
232
  ```ruby
218
233
  # Can be true or false
@@ -223,12 +238,24 @@ JitPreloader.globally_enabled = true
223
238
  # so that you can turn it on or off dynamically.
224
239
  JitPreloader.globally_enabled = ->{ $redis.get('always_jit_preload') == 'on' }
225
240
 
241
+ # Setting global max ids constraint on all aggregation methods.
242
+ JitPreloader.max_ids_per_query = 10
243
+
244
+ class Contact < ActiveRecord::Base
245
+ has_many :emails
246
+ has_many_aggregate :emails, :count_all, :count, "*"
247
+ end
248
+
226
249
  # When enabled globally, this would not generate an N+1 query.
227
250
  Contact.all.each do |contact|
228
251
  contact.emails.each do |email|
229
252
  # do something
230
253
  end
254
+ # When max_ides_per_query is set globally, the aggregate method will split query base on the limit.
255
+ contact.emails_count_all
231
256
  end
257
+
258
+
232
259
  ```
233
260
 
234
261
  ## What it doesn't solve
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "activerecord", ">= 7", "< 8"
21
+ spec.add_dependency "activerecord", "< 8"
22
22
  spec.add_dependency "activesupport"
23
23
 
24
24
  spec.add_development_dependency "bundler"
@@ -5,19 +5,17 @@ module JitPreloader
5
5
  # below. Our changes here are that we remove records that are already
6
6
  # part of the target, then attach all of the records to a new jit preloader.
7
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
8
+ # def run
9
+ # records = records_by_owner
14
10
 
15
11
  # owners.each do |owner|
16
- # associate_records_to_owner(owner, records[convert_key(owner[owner_key_name])] || [])
17
- # end
12
+ # associate_records_to_owner(owner, records[owner] || [])
13
+ # end if @associate
14
+
15
+ # self
18
16
  # end
19
17
 
20
- def run(preloader)
18
+ def run
21
19
  return unless (reflection.scope.nil? || reflection.scope.arity == 0) && klass.ancestors.include?(ActiveRecord::Base)
22
20
 
23
21
  super.tap do
@@ -29,31 +27,30 @@ module JitPreloader
29
27
 
30
28
  # Original method:
31
29
  # def associate_records_to_owner(owner, records)
30
+ # return if loaded?(owner)
31
+ #
32
32
  # association = owner.association(reflection.name)
33
- # association.loaded!
33
+ #
34
34
  # if reflection.collection?
35
- # association.target.concat(records)
35
+ # association.target = records
36
36
  # else
37
- # association.target = records.first unless records.empty?
37
+ # association.target = records.first
38
38
  # end
39
39
  # end
40
40
  def associate_records_to_owner(owner, records)
41
+ return if loaded?(owner)
42
+
41
43
  association = owner.association(reflection.name)
42
- association.loaded!
43
44
 
44
45
  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
46
  new_records = association.target.any? ? records - association.target : records
49
47
  association.target.concat(new_records)
50
48
  association.loaded!
51
49
  else
52
- association.target = records.first unless records.empty?
50
+ association.target = records.first
53
51
  end
54
52
  end
55
53
 
56
-
57
54
  def build_scope
58
55
  super.tap do |scope|
59
56
  scope.jit_preload! if owners.any?(&:jit_preloader) || JitPreloader.globally_enabled?
@@ -0,0 +1,22 @@
1
+ module JitPreloader
2
+ module PreloaderBranch
3
+ """
4
+ ActiveRecord version >= 7.x.x introduced an improvement for preloading associations in batches:
5
+ https://github.com/rails/rails/blob/main/activerecord/lib/active_record/associations/preloader.rb#L121
6
+
7
+ Our existing monkey-patches will ignore associations whose classes are not descendants of
8
+ ActiveRecord::Base (example: https://github.com/clio/jit_preloader/blob/master/lib/jit_preloader/active_record/associations/preloader/ar6_association.rb#L19).
9
+ But this change breaks that behaviour because now Batch is calling `klass.base_class` (a method defined by ActiveRecord::Base)
10
+ before we have a chance to filter out the non-AR classes.
11
+ This patch for AR 7.x makes the Branch class ignore any association loaders that aren't for ActiveRecord::Base subclasses.
12
+ """
13
+
14
+ def loaders
15
+ @loaders = super.find_all do |loader|
16
+ loader.klass < ::ActiveRecord::Base
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ ActiveRecord::Associations::Preloader::Branch.prepend(JitPreloader::PreloaderBranch)
@@ -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
 
@@ -18,7 +18,7 @@ module JitPreloadExtension
18
18
  end
19
19
  end
20
20
 
21
- if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("6.0.0")
21
+ if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("7.0.0")
22
22
  def preload_scoped_relation(name:, base_association:, preload_scope: nil)
23
23
  return jit_preload_scoped_relations[name] if jit_preload_scoped_relations&.key?(name)
24
24
 
@@ -90,7 +90,7 @@ module JitPreloadExtension
90
90
  class << base
91
91
  delegate :jit_preload, to: :all
92
92
 
93
- def has_many_aggregate(assoc, name, aggregate, field, table_alias_name: nil, default: 0)
93
+ def has_many_aggregate(assoc, name, aggregate, field, table_alias_name: nil, default: 0, max_ids_per_query: nil)
94
94
  method_name = "#{assoc}_#{name}"
95
95
 
96
96
  define_method(method_name) do |conditions={}|
@@ -101,6 +101,13 @@ module JitPreloadExtension
101
101
  if jit_preloader
102
102
  reflection = association(assoc).reflection
103
103
  primary_ids = jit_preloader.records.collect{|r| r[reflection.active_record_primary_key] }
104
+ max_ids_per_query = max_ids_per_query || JitPreloader.max_ids_per_query
105
+ if max_ids_per_query
106
+ slices = primary_ids.each_slice(max_ids_per_query)
107
+ else
108
+ slices = [primary_ids]
109
+ end
110
+
104
111
  klass = reflection.klass
105
112
 
106
113
  aggregate_association = reflection
@@ -115,15 +122,13 @@ module JitPreloadExtension
115
122
  table_reference = table_alias_name
116
123
  table_reference ||= association_scope.references_values.first || aggregate_association.table_name
117
124
 
118
- conditions[table_reference] = { aggregate_association.foreign_key => primary_ids }
119
-
120
125
  # If the association is a STI child model, specify its type in the condition so that it
121
126
  # doesn't include results from other child models
122
127
  parent_is_base_class = aggregate_association.klass.superclass.abstract_class? || aggregate_association.klass.superclass == ActiveRecord::Base
123
128
  has_type_column = aggregate_association.klass.column_names.include?(aggregate_association.klass.inheritance_column)
124
129
  is_child_sti_model = !parent_is_base_class && has_type_column
125
130
  if is_child_sti_model
126
- conditions[table_reference].merge!({ aggregate_association.klass.inheritance_column => aggregate_association.klass.sti_name })
131
+ conditions[table_reference] = { aggregate_association.klass.inheritance_column => aggregate_association.klass.sti_name }
127
132
  end
128
133
 
129
134
  if reflection.type.present?
@@ -131,11 +136,15 @@ module JitPreloadExtension
131
136
  end
132
137
  group_by = "#{table_reference}.#{aggregate_association.foreign_key}"
133
138
 
134
- preloaded_data = Hash[association_scope
135
- .where(conditions)
136
- .group(group_by)
137
- .send(aggregate, field)
138
- ]
139
+ preloaded_data = {}
140
+ slices.each do |slice|
141
+ data = Hash[association_scope
142
+ .where(conditions.deep_merge(table_reference => { aggregate_association.foreign_key => slice }))
143
+ .group(group_by)
144
+ .send(aggregate, field)
145
+ ]
146
+ preloaded_data.merge!(data)
147
+ end
139
148
 
140
149
  jit_preloader.records.each do |record|
141
150
  record.jit_preload_aggregates ||= {}
@@ -3,21 +3,47 @@ module JitPreloader
3
3
 
4
4
  attr_accessor :records
5
5
 
6
- def self.attach(records)
7
- new(records: records.dup, associations: nil).tap do |loader|
8
- records.each do |record|
9
- record.jit_preloader = loader
6
+ if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("7.0.0")
7
+ def self.attach(records)
8
+ new(records: records.dup, associations: nil).tap do |loader|
9
+ records.each do |record|
10
+ record.jit_preloader = loader
11
+ end
10
12
  end
11
13
  end
12
- end
13
14
 
14
- def jit_preload(associations)
15
- # It is possible that the records array has multiple different classes (think single table inheritance).
16
- # Thus, it is possible that some of the records don't have an association.
17
- records_with_association = records.reject{|r| r.class.reflect_on_association(associations).nil? }
18
- self.class.new(records: records_with_association, associations: associations).call
15
+ def jit_preload(associations)
16
+ # It is possible that the records array has multiple different classes (think single table inheritance).
17
+ # Thus, it is possible that some of the records don't have an association.
18
+ records_with_association = records.reject{|r| r.class.reflect_on_association(associations).nil? }
19
+
20
+ # Some of the records may already have the association loaded and we should not load them again
21
+ records_requiring_loading = records_with_association.select{|r| !r.association(associations).loaded? }
22
+
23
+ self.class.new(records: records_requiring_loading, associations: associations).call
24
+ end
25
+ else
26
+ def self.attach(records)
27
+ new.tap do |loader|
28
+ loader.records = records.dup
29
+ records.each do |record|
30
+ record.jit_preloader = loader
31
+ end
32
+ end
33
+ end
34
+
35
+ def jit_preload(associations)
36
+ # It is possible that the records array has multiple different classes (think single table inheritance).
37
+ # Thus, it is possible that some of the records don't have an association.
38
+ records_with_association = records.reject{ |record| record.class.reflect_on_association(associations).nil? }
39
+
40
+ # Some of the records may already have the association loaded and we should not load them again
41
+ records_requiring_loading = records_with_association.select{ |record| !record.association(associations).loaded? }
42
+ preload records_with_association, associations
43
+ end
19
44
  end
20
45
 
46
+
21
47
  # We do not want the jit_preloader to be dumpable
22
48
  # If you dump a ActiveRecord::Base object that has a jit_preloader instance variable
23
49
  # you will also end up dumping all of the records the preloader has reference to.
@@ -1,3 +1,3 @@
1
1
  module JitPreloader
2
- VERSION = "2.0.0"
2
+ VERSION = "3.0.0"
3
3
  end
data/lib/jit_preloader.rb CHANGED
@@ -8,10 +8,11 @@ require 'jit_preloader/active_record/base'
8
8
  require 'jit_preloader/active_record/relation'
9
9
  require 'jit_preloader/active_record/associations/collection_association'
10
10
  require 'jit_preloader/active_record/associations/singular_association'
11
- if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("6.0.0")
11
+ if Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("7.0.0")
12
+ require 'jit_preloader/active_record/associations/preloader/ar7_association'
13
+ require 'jit_preloader/active_record/associations/preloader/ar7_branch'
14
+ elsif Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("6.1.0")
12
15
  require 'jit_preloader/active_record/associations/preloader/ar6_association'
13
- elsif Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new("5.2.2")
14
- require 'jit_preloader/active_record/associations/preloader/ar5_association'
15
16
  else
16
17
  require 'jit_preloader/active_record/associations/preloader/collection_association'
17
18
  require 'jit_preloader/active_record/associations/preloader/singular_association'
@@ -23,6 +24,16 @@ module JitPreloader
23
24
  @enabled = value
24
25
  end
25
26
 
27
+ def self.max_ids_per_query=(max_ids)
28
+ if max_ids && max_ids >= 1
29
+ @max_ids_per_query = max_ids
30
+ end
31
+ end
32
+
33
+ def self.max_ids_per_query
34
+ @max_ids_per_query
35
+ end
36
+
26
37
  def self.globally_enabled?
27
38
  if @enabled && @enabled.respond_to?(:call)
28
39
  @enabled.call
@@ -1,4 +1,5 @@
1
1
  require "spec_helper"
2
+ require "db-query-matchers"
2
3
 
3
4
  RSpec.describe JitPreloader::Preloader do
4
5
  let!(:contact1) do
@@ -164,6 +165,30 @@ RSpec.describe JitPreloader::Preloader do
164
165
  expect(Contact.jit_preload.map(&:contact_owner)).to eq [nil, ContactOwner.first, Address.first]
165
166
  end
166
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
167
192
  end
168
193
  end
169
194
 
@@ -479,6 +504,69 @@ RSpec.describe JitPreloader::Preloader do
479
504
  end
480
505
  end
481
506
  end
507
+
508
+ context "with dive limit set" do
509
+ let!(:contact_book_1) { ContactBook.create(name: "The Yellow Pages") }
510
+ let!(:contact_book_2) { ContactBook.create(name: "The Yellow Pages") }
511
+ let!(:contact_book_3) { ContactBook.create(name: "The Yellow Pages") }
512
+ let!(:company1) { Company.create(name: "Company1", contact_book: contact_book_1) }
513
+ let!(:company2) { Company.create(name: "Company2", contact_book: contact_book_1) }
514
+ let!(:company3) { Company.create(name: "Company2", contact_book: contact_book_2) }
515
+ let!(:company4) { Company.create(name: "Company4", contact_book: contact_book_3) }
516
+ let!(:company5) { Company.create(name: "Company5", contact_book: contact_book_3) }
517
+
518
+ context "from the global value" do
519
+ before do
520
+ JitPreloader.max_ids_per_query = 2
521
+ end
522
+
523
+ after do
524
+ JitPreloader.max_ids_per_query = nil
525
+ end
526
+
527
+ it "can handle queries" do
528
+ contact_books = ContactBook.jit_preload.to_a
529
+
530
+ expect(contact_books.first.companies_count).to eq 2
531
+ expect(contact_books.second.companies_count).to eq 1
532
+ expect(contact_books.last.companies_count).to eq 2
533
+ end
534
+
535
+ it "makes the right number of queries based on dive limit" do
536
+ contact_books = ContactBook.jit_preload.to_a
537
+ expect do
538
+ contact_books.first.companies_count
539
+ end.to make_database_queries(count: 2)
540
+
541
+ expect do
542
+ contact_books.second.companies_count
543
+ contact_books.last.companies_count
544
+ end.to_not make_database_queries
545
+ end
546
+ end
547
+
548
+ context "from aggregate argument" do
549
+ it "can handle queries" do
550
+ contact_books = ContactBook.jit_preload.to_a
551
+
552
+ expect(contact_books.first.companies_count_with_max_ids_set).to eq 2
553
+ expect(contact_books.second.companies_count_with_max_ids_set).to eq 1
554
+ expect(contact_books.last.companies_count_with_max_ids_set).to eq 2
555
+ end
556
+
557
+ it "makes the right number of queries based on dive limit" do
558
+ contact_books = ContactBook.jit_preload.to_a
559
+ expect do
560
+ contact_books.first.companies_count_with_max_ids_set
561
+ end.to make_database_queries(count: 2)
562
+
563
+ expect do
564
+ contact_books.second.companies_count_with_max_ids_set
565
+ contact_books.last.companies_count_with_max_ids_set
566
+ end.to_not make_database_queries
567
+ end
568
+ end
569
+ end
482
570
  end
483
571
 
484
572
  end
@@ -10,6 +10,7 @@ class ContactBook < ActiveRecord::Base
10
10
  has_many :children, through: :parents
11
11
 
12
12
  has_many_aggregate :companies, :count, :count, "*"
13
+ has_many_aggregate :companies, :count_with_max_ids_set, :count, "*", max_ids_per_query: 2
13
14
  has_many_aggregate :employees, :count, :count, "*"
14
15
  has_many_aggregate :company_employees, :count, :count, "*"
15
16
  has_many_aggregate :children, :count, :count, "*"
metadata CHANGED
@@ -1,22 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jit_preloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.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: 2022-05-18 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
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '7'
20
17
  - - "<"
21
18
  - !ruby/object:Gem::Version
22
19
  version: '8'
@@ -24,9 +21,6 @@ dependencies:
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '7'
30
24
  - - "<"
31
25
  - !ruby/object:Gem::Version
32
26
  version: '8'
@@ -152,12 +146,11 @@ extensions: []
152
146
  extra_rdoc_files: []
153
147
  files:
154
148
  - ".github/CODEOWNERS"
149
+ - ".github/workflows/ci.yml"
155
150
  - ".github/workflows/gem-push.yml"
156
151
  - ".gitignore"
157
152
  - ".rspec"
158
153
  - Gemfile
159
- - Gemfile.5.2
160
- - Gemfile.5.2.lock
161
154
  - Gemfile.6.0
162
155
  - Gemfile.6.0.lock
163
156
  - Gemfile.6.1
@@ -168,8 +161,9 @@ files:
168
161
  - jit_preloader.gemspec
169
162
  - lib/jit_preloader.rb
170
163
  - lib/jit_preloader/active_record/associations/collection_association.rb
171
- - lib/jit_preloader/active_record/associations/preloader/ar5_association.rb
172
164
  - lib/jit_preloader/active_record/associations/preloader/ar6_association.rb
165
+ - lib/jit_preloader/active_record/associations/preloader/ar7_association.rb
166
+ - lib/jit_preloader/active_record/associations/preloader/ar7_branch.rb
173
167
  - lib/jit_preloader/active_record/associations/preloader/collection_association.rb
174
168
  - lib/jit_preloader/active_record/associations/preloader/singular_association.rb
175
169
  - lib/jit_preloader/active_record/associations/singular_association.rb
@@ -201,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
195
  - !ruby/object:Gem::Version
202
196
  version: '0'
203
197
  requirements: []
204
- rubygems_version: 3.1.6
198
+ rubygems_version: 3.3.27
205
199
  signing_key:
206
200
  specification_version: 4
207
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