Skip to content

Commit b3d037f

Browse files
authored
FWK-1615 Prevent unnecessary database connections (#8)
1 parent 72e04ad commit b3d037f

File tree

8 files changed

+157
-14
lines changed

8 files changed

+157
-14
lines changed

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
.config
55
.yardoc
66
.idea
7-
Gemfile.lock
87
InstalledFiles
98
_yardoc
109
coverage
@@ -21,6 +20,5 @@ tmp
2120
*.o
2221
*.a
2322
mkmf.log
24-
.ruby-version
2523
coverage/
2624
results.xml

.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.1.3

Gemfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,14 @@ source 'https://rubygems.org'
22

33
# Specify your gem's dependencies in activerecord-delay_touching.gemspec
44
gemspec
5+
6+
gem "rake"
7+
8+
group :test do
9+
gem "sqlite3"
10+
gem "timecop"
11+
gem "rspec-rails"
12+
gem "simplecov"
13+
gem "simplecov-rcov"
14+
gem "yarjuf"
15+
end

Gemfile.lock

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
PATH
2+
remote: .
3+
specs:
4+
activerecord-delay_touching (1.1.2)
5+
activerecord (>= 4.2, < 6.2)
6+
7+
GEM
8+
remote: https://rubygems.org/
9+
specs:
10+
actionpack (6.1.7.2)
11+
actionview (= 6.1.7.2)
12+
activesupport (= 6.1.7.2)
13+
rack (~> 2.0, >= 2.0.9)
14+
rack-test (>= 0.6.3)
15+
rails-dom-testing (~> 2.0)
16+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
17+
actionview (6.1.7.2)
18+
activesupport (= 6.1.7.2)
19+
builder (~> 3.1)
20+
erubi (~> 1.4)
21+
rails-dom-testing (~> 2.0)
22+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
23+
activemodel (6.1.7.2)
24+
activesupport (= 6.1.7.2)
25+
activerecord (6.1.7.2)
26+
activemodel (= 6.1.7.2)
27+
activesupport (= 6.1.7.2)
28+
activesupport (6.1.7.2)
29+
concurrent-ruby (~> 1.0, >= 1.0.2)
30+
i18n (>= 1.6, < 2)
31+
minitest (>= 5.1)
32+
tzinfo (~> 2.0)
33+
zeitwerk (~> 2.3)
34+
builder (3.2.4)
35+
concurrent-ruby (1.2.2)
36+
crass (1.0.6)
37+
diff-lcs (1.5.0)
38+
docile (1.4.0)
39+
erubi (1.12.0)
40+
i18n (1.12.0)
41+
concurrent-ruby (~> 1.0)
42+
loofah (2.19.1)
43+
crass (~> 1.0.2)
44+
nokogiri (>= 1.5.9)
45+
method_source (1.0.0)
46+
mini_portile2 (2.8.1)
47+
minitest (5.18.0)
48+
nokogiri (1.14.2)
49+
mini_portile2 (~> 2.8.0)
50+
racc (~> 1.4)
51+
racc (1.6.2)
52+
rack (2.2.6.3)
53+
rack-test (2.0.2)
54+
rack (>= 1.3)
55+
rails-dom-testing (2.0.3)
56+
activesupport (>= 4.2.0)
57+
nokogiri (>= 1.6)
58+
rails-html-sanitizer (1.5.0)
59+
loofah (~> 2.19, >= 2.19.1)
60+
railties (6.1.7.2)
61+
actionpack (= 6.1.7.2)
62+
activesupport (= 6.1.7.2)
63+
method_source
64+
rake (>= 12.2)
65+
thor (~> 1.0)
66+
rake (13.0.6)
67+
rspec (3.12.0)
68+
rspec-core (~> 3.12.0)
69+
rspec-expectations (~> 3.12.0)
70+
rspec-mocks (~> 3.12.0)
71+
rspec-core (3.12.1)
72+
rspec-support (~> 3.12.0)
73+
rspec-expectations (3.12.2)
74+
diff-lcs (>= 1.2.0, < 2.0)
75+
rspec-support (~> 3.12.0)
76+
rspec-mocks (3.12.3)
77+
diff-lcs (>= 1.2.0, < 2.0)
78+
rspec-support (~> 3.12.0)
79+
rspec-rails (6.0.1)
80+
actionpack (>= 6.1)
81+
activesupport (>= 6.1)
82+
railties (>= 6.1)
83+
rspec-core (~> 3.11)
84+
rspec-expectations (~> 3.11)
85+
rspec-mocks (~> 3.11)
86+
rspec-support (~> 3.11)
87+
rspec-support (3.12.0)
88+
simplecov (0.22.0)
89+
docile (~> 1.1)
90+
simplecov-html (~> 0.11)
91+
simplecov_json_formatter (~> 0.1)
92+
simplecov-html (0.12.3)
93+
simplecov-rcov (0.3.1)
94+
simplecov (>= 0.4.1)
95+
simplecov_json_formatter (0.1.4)
96+
sqlite3 (1.6.1)
97+
mini_portile2 (~> 2.8.0)
98+
thor (1.2.1)
99+
timecop (0.9.6)
100+
tzinfo (2.0.6)
101+
concurrent-ruby (~> 1.0)
102+
yarjuf (2.0.0)
103+
builder
104+
rspec (~> 3)
105+
zeitwerk (2.6.7)
106+
107+
PLATFORMS
108+
ruby
109+
110+
DEPENDENCIES
111+
activerecord-delay_touching!
112+
rake
113+
rspec-rails
114+
simplecov
115+
simplecov-rcov
116+
sqlite3
117+
timecop
118+
yarjuf
119+
120+
BUNDLED WITH
121+
2.4.7

Rakefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ require "bundler/gem_tasks"
22
require "rspec/core"
33
require "rspec/core/rake_task"
44

5-
Rake::Task["spec"].clear
65
RSpec::Core::RakeTask.new(:spec) do |t|
76
t.fail_on_error = false
87
t.rspec_opts = %w[-f JUnit -o results.xml]

activerecord-delay_touching.gemspec

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,4 @@ Gem::Specification.new do |spec|
1919
spec.require_paths = ["lib"]
2020

2121
spec.add_dependency "activerecord", ">= 4.2", "< 6.2"
22-
23-
spec.add_development_dependency "bundler", "~> 1.6"
24-
spec.add_development_dependency "rake"
25-
spec.add_development_dependency "sqlite3"
26-
spec.add_development_dependency "timecop"
27-
spec.add_development_dependency "rspec-rails", "~> 3.0"
28-
spec.add_development_dependency "simplecov"
29-
spec.add_development_dependency "simplecov-rcov"
30-
spec.add_development_dependency "yarjuf"
3122
end

lib/activerecord/delay_touching.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ def self.call
6161

6262
# Apply the touches that were delayed.
6363
def self.apply
64-
begin
64+
while state.more_records?
6565
ActiveRecord::Base.transaction do
6666
state.records_by_attrs_and_class.each do |attr, classes_and_records|
6767
classes_and_records.each do |klass, records|
6868
touch_records attr, klass, records
6969
end
7070
end
7171
end
72-
end while state.more_records?
72+
end
7373
ensure
7474
state.clear_records
7575
end

spec/activerecord/delay_touching_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,28 @@
125125
end
126126
end
127127

128+
it 'will not connect to the database if there are no touches' do
129+
expect(ActiveRecord::Base).not_to receive(:connection)
130+
ActiveRecord::Base.delay_touching do
131+
# no touches, so no reason to fetch a connection
132+
end
133+
end
134+
135+
it 'will not connect to the database if none of the touches are persisted' do
136+
expect(ActiveRecord::Base).not_to receive(:connection)
137+
ActiveRecord::Base.delay_touching do
138+
Pet.new.touch # not persisted, so won't cause updates
139+
end
140+
end
141+
142+
it 'still connects to the database for other queries, even if there are no touches' do
143+
expect(ActiveRecord::Base.connection).not_to receive(:update) # no touches
144+
expect(ActiveRecord::Base).to receive(:connection).at_least(:once).and_call_original
145+
ActiveRecord::Base.delay_touching do
146+
expect(Pet.count).to be >= 0 # query should still work
147+
end
148+
end
149+
128150
context 'touch: true' do
129151
before do
130152
person.pets << pet1

0 commit comments

Comments
 (0)