jit_preloader 0.0.4 → 0.0.5
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/.gitignore +1 -0
- data/lib/jit_preloader/active_record/base.rb +8 -5
- data/lib/jit_preloader/version.rb +1 -1
- data/spec/lib/jit_preloader/preloader_spec.rb +33 -27
- data/spec/support/database.rb +1 -0
- data/spec/support/models.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b6500123613b4cac00d676d731cb65eb59ce847
|
4
|
+
data.tar.gz: 940e041e05f643ee35ca43bd192ade9c1a5b5857
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 425c551f3a1daf7c21120cb9290b294dc4cb9f0d17b6b0b614ab3d13fafdedb793229cbdcf0dc1e337e5f5b05f1e36d476347a94b5c855dfee0303a97b36083e
|
7
|
+
data.tar.gz: 06ca2ebee6226d8d51ef465c4e2a5bde86ad9231a1f5d6249a3681f74f9830946886e1716f0b76b85709ed946ca09b9087b5165a1b3ac4ce06a568a4386731a0
|
data/.gitignore
CHANGED
@@ -12,9 +12,12 @@ module JitPreloadExtension
|
|
12
12
|
delegate :jit_preload, to: :all
|
13
13
|
|
14
14
|
def has_many_aggregate(assoc, name, aggregate, field, default: 0)
|
15
|
-
|
15
|
+
method_name = "#{assoc}_#{name}"
|
16
|
+
|
17
|
+
define_method(method_name) do
|
16
18
|
self.jit_preload_aggregates ||= {}
|
17
|
-
|
19
|
+
|
20
|
+
return jit_preload_aggregates[method_name] if jit_preload_aggregates[method_name]
|
18
21
|
if jit_preloader
|
19
22
|
reflection = association(assoc).reflection
|
20
23
|
primary_ids = jit_preloader.records.collect{|r| r[reflection.active_record_primary_key] }
|
@@ -28,12 +31,12 @@ module JitPreloadExtension
|
|
28
31
|
|
29
32
|
jit_preloader.records.each do |record|
|
30
33
|
record.jit_preload_aggregates ||= {}
|
31
|
-
record.jit_preload_aggregates[
|
34
|
+
record.jit_preload_aggregates[method_name] = preloaded_data[record.id] || default
|
32
35
|
end
|
33
36
|
else
|
34
|
-
self.jit_preload_aggregates[
|
37
|
+
self.jit_preload_aggregates[method_name] = send(assoc).send(aggregate, field) || default
|
35
38
|
end
|
36
|
-
jit_preload_aggregates[
|
39
|
+
jit_preload_aggregates[method_name]
|
37
40
|
end
|
38
41
|
|
39
42
|
def reload(*args)
|
@@ -3,31 +3,32 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe JitPreloader::Preloader do
|
4
4
|
|
5
5
|
let!(:contact1) do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
addresses = [
|
7
|
+
Address.new(street: "123 Fake st", country: canada),
|
8
|
+
Address.new(street: "21 Jump st", country: usa)
|
9
|
+
]
|
10
|
+
phones = [
|
11
|
+
PhoneNumber.new(phone: "4445556666"),
|
12
|
+
PhoneNumber.new(phone: "2223333444")
|
13
|
+
]
|
14
|
+
Contact.create(name: "Only Addresses", addresses: addresses, phone_numbers: phones)
|
13
15
|
end
|
14
16
|
|
15
17
|
let!(:contact2) do
|
16
|
-
Contact.create(
|
17
|
-
name: "Only Emails",
|
18
|
-
email_address: EmailAddress.new(address: "woot@woot.com"),
|
19
|
-
)
|
18
|
+
Contact.create(name: "Only Emails", email_address: EmailAddress.new(address: "woot@woot.com"))
|
20
19
|
end
|
21
20
|
|
22
21
|
let!(:contact3) do
|
22
|
+
addresses = [
|
23
|
+
Address.new(street: "1 First st", country: canada),
|
24
|
+
Address.new(street: "10 Tenth Ave", country: usa)
|
25
|
+
]
|
23
26
|
Contact.create(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
email_address: EmailAddress.new(address: "woot@woot.com"),
|
30
|
-
)
|
27
|
+
name: "Both!",
|
28
|
+
addresses: addresses,
|
29
|
+
email_address: EmailAddress.new(address: "woot@woot.com"),
|
30
|
+
phone_numbers: [PhoneNumber.new(phone: "1234567890")]
|
31
|
+
)
|
31
32
|
end
|
32
33
|
|
33
34
|
let(:canada) { Country.create(name: "Canada") }
|
@@ -39,30 +40,35 @@ RSpec.describe JitPreloader::Preloader do
|
|
39
40
|
end
|
40
41
|
|
41
42
|
context "when preloading an aggregate" do
|
43
|
+
let(:addresses_counts) { [2, 0, 2] }
|
44
|
+
let(:phone_number_counts) { [2, 0, 1] }
|
45
|
+
let(:maxes) { [11, 0, 12] }
|
46
|
+
|
42
47
|
context "without jit_preload" do
|
43
48
|
it "generates N+1 query notifications for each one" do
|
44
49
|
ActiveSupport::Notifications.subscribed(callback, "n_plus_one_query") do
|
45
|
-
counts = [2,0,2]
|
46
|
-
maxes = [11,0,12]
|
47
50
|
Contact.all.each_with_index do |c, i|
|
48
|
-
expect(c.addresses_count).to eql
|
51
|
+
expect(c.addresses_count).to eql addresses_counts[i]
|
49
52
|
expect(c.addresses_max_street_length).to eql maxes[i]
|
53
|
+
expect(c.phone_numbers_count).to eql phone_number_counts[i]
|
50
54
|
end
|
51
55
|
end
|
52
|
-
|
56
|
+
|
57
|
+
contact_queries = [contact1, contact2, contact3].product([["addresses.count", "addresses.maximum", "phone_numbers.count"]])
|
53
58
|
expect(source_map).to eql(Hash[contact_queries])
|
54
59
|
end
|
55
60
|
end
|
56
|
-
|
57
|
-
|
61
|
+
|
62
|
+
context "with jit_preload" do
|
63
|
+
it "doesn NOT generate N+1 query notifications" do
|
58
64
|
ActiveSupport::Notifications.subscribed(callback, "n_plus_one_query") do
|
59
|
-
counts = [2,0,2]
|
60
|
-
maxes = [11,0,12]
|
61
65
|
Contact.jit_preload.each_with_index do |c, i|
|
62
|
-
expect(c.addresses_count).to eql
|
66
|
+
expect(c.addresses_count).to eql addresses_counts[i]
|
63
67
|
expect(c.addresses_max_street_length).to eql maxes[i]
|
68
|
+
expect(c.phone_numbers_count).to eql phone_number_counts[i]
|
64
69
|
end
|
65
70
|
end
|
71
|
+
|
66
72
|
expect(source_map).to eql({})
|
67
73
|
end
|
68
74
|
end
|
data/spec/support/database.rb
CHANGED
@@ -4,6 +4,7 @@ class Database
|
|
4
4
|
"CREATE TABLE contacts (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(255))",
|
5
5
|
"CREATE TABLE addresses (id INTEGER NOT NULL PRIMARY KEY, contact_id INTEGER NOT NULL, country_id INTEGER NOT NULL, street VARCHAR(255))",
|
6
6
|
"CREATE TABLE email_addresses (id INTEGER NOT NULL PRIMARY KEY, contact_id INTEGER NOT NULL, address VARCHAR(255))",
|
7
|
+
"CREATE TABLE phone_numbers (id INTEGER NOT NULL PRIMARY KEY, contact_id INTEGER NOT NULL, phone VARCHAR(10))",
|
7
8
|
"CREATE TABLE countries (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(255))",
|
8
9
|
]
|
9
10
|
end
|
data/spec/support/models.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
class Contact < ActiveRecord::Base
|
2
2
|
has_many :addresses
|
3
|
+
has_many :phone_numbers
|
3
4
|
has_one :email_address
|
4
5
|
|
5
6
|
has_many_aggregate :addresses, :max_street_length, :maximum, "LENGTH(street)"
|
7
|
+
has_many_aggregate :phone_numbers, :count, :count, "id"
|
6
8
|
has_many_aggregate :addresses, :count, :count, "*"
|
7
9
|
end
|
8
10
|
|
@@ -15,6 +17,10 @@ class EmailAddress < ActiveRecord::Base
|
|
15
17
|
belongs_to :contact
|
16
18
|
end
|
17
19
|
|
20
|
+
class PhoneNumber < ActiveRecord::Base
|
21
|
+
belongs_to :contact
|
22
|
+
end
|
23
|
+
|
18
24
|
class Country < ActiveRecord::Base
|
19
25
|
has_many :addresses
|
20
26
|
end
|
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: 0.0.
|
4
|
+
version: 0.0.5
|
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: 2017-01-
|
11
|
+
date: 2017-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|