Skip to content

Commit 9659826

Browse files
when_committed! will run immediately if not in a transaction
If you call `when_committed` outside of a transaction, and never save the model, the block will never run. This may be exactly what you want, since the block might depend on changes to the model. `when_committed!` is useful in scenarios where you don't know if the code will be called as part of a transaction or other model change. If it happens as part of transaction, wait until it is committed.
1 parent 844b718 commit 9659826

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

lib/when_committed.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ def when_committed(&block)
1111
when_committed_callbacks << block
1212
end
1313

14+
def when_committed!(&block)
15+
if self.connection.open_transactions > 0
16+
when_committed(&block)
17+
else
18+
block.call
19+
end
20+
end
21+
1422
private
1523

1624
def when_committed_callbacks

spec/when_committed_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,33 @@
2121
model.should respond_to(:when_committed)
2222
end
2323

24+
describe "#when_committed!" do
25+
before do
26+
Backgrounder.reset
27+
end
28+
let(:model) { Widget.new }
29+
30+
context "when not running within a transaction" do
31+
it "runs the block immediately" do
32+
model.needs_to_happen
33+
Backgrounder.jobs.should == [:important_work]
34+
end
35+
end
36+
37+
context "when running within a transaction" do
38+
it "does not run the provided block until the transaction is committed" do
39+
Widget.transaction do
40+
model.needs_to_happen
41+
Backgrounder.jobs.should be_empty
42+
model.save
43+
Backgrounder.jobs.should be_empty
44+
end
45+
Backgrounder.jobs.should == [:important_work]
46+
end
47+
end
48+
49+
end
50+
2451
describe "#when_committed" do
2552
before do
2653
Backgrounder.reset
@@ -83,6 +110,9 @@ class Widget < ActiveRecord::Base
83110
def action_that_needs_follow_up_after_commit
84111
when_committed { Backgrounder.enqueue :important_work }
85112
end
113+
def needs_to_happen
114+
when_committed! { Backgrounder.enqueue :important_work }
115+
end
86116
def another_action_with_follow_up
87117
when_committed { Backgrounder.enqueue :more_work }
88118
end

0 commit comments

Comments
 (0)