Skip to content

Commit

Permalink
introduction of before transaction and after transaction callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
HoyaBoya committed Nov 5, 2015
1 parent 8002e5a commit 5e1a30e
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 7 deletions.
4 changes: 2 additions & 2 deletions lib/aasm/aasm.rb
Expand Up @@ -103,12 +103,12 @@ def aasm_fire_event(state_machine_name, event_name, options, *args, &block)
aasm_failed(state_machine_name, event_name, old_state)
end
rescue StandardError => e
event.fire_callbacks(:error, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) ||
event.fire_callbacks(:error, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) ||
event.fire_global_callbacks(:error_on_all_events, self, e, *process_args(event, aasm(state_machine_name).current_state, *args)) ||
raise(e)
ensure
event.fire_callbacks(:ensure, self, *process_args(event, aasm(state_machine_name).current_state, *args))
event.fire_global_callbacks(:ensure_on_all_events, self, *process_args(event, aasm(state_machine_name).current_state, *args))
event.fire_global_callbacks(:ensure_on_all_events, self, *process_args(event, aasm(state_machine_name).current_state, *args))
end
end

Expand Down
11 changes: 10 additions & 1 deletion lib/aasm/core/event.rb
Expand Up @@ -13,7 +13,16 @@ def initialize(name, state_machine, options = {}, &block)

# from aasm4
@options = options # QUESTION: .dup ?
add_options_from_dsl(@options, [:after, :before, :error, :success, :after_commit, :ensure], &block) if block
add_options_from_dsl(@options, [
:after,
:after_commit,
:after_transaction,
:before,
:before_transaction,
:ensure,
:error,
:success,
], &block) if block
end

# a neutered version of fire - it doesn't actually fire the event, it just
Expand Down
21 changes: 17 additions & 4 deletions lib/aasm/persistence/active_record_persistence.rb
Expand Up @@ -145,11 +145,24 @@ def aasm_ensure_initial_state
end

def aasm_fire_event(state_machine_name, name, options, *args, &block)
success = options[:persist] ? self.class.transaction(:requires_new => requires_new?(state_machine_name)) { super } : super
event = self.class.aasm(state_machine_name).state_machine.events[name]

if success && options[:persist]
event = self.class.aasm(state_machine_name).state_machine.events[name]
event.fire_callbacks(:after_commit, self, *args)
if options[:persist]
event.fire_callbacks(:before_transaction, self, *args)
event.fire_global_callbacks(:before_all_transactions, self, *args)
end

begin
success = options[:persist] ? self.class.transaction(:requires_new => requires_new?(state_machine_name)) { super } : super
if options[:persist] && success
event.fire_callbacks(:after_commit, self, *args)
event.fire_global_callbacks(:after_all_commits, self, *args)
end
ensure
if options[:persist]
event.fire_callbacks(:after_transaction, self, *args)
event.fire_global_callbacks(:after_all_transactions, self, *args)
end
end

success
Expand Down
24 changes: 24 additions & 0 deletions spec/models/validator.rb
Expand Up @@ -2,22 +2,46 @@

class Validator < ActiveRecord::Base

attr_accessor :after_transaction_performed_on_fail,
:after_transaction_performed_on_run,
:before_transaction_performed_on_fail,
:before_transaction_performed_on_run

include AASM

aasm :column => :status do
state :sleeping, :initial => true
state :running
state :failed, :after_enter => :fail

event :run, :after_commit => :change_name! do
after_transaction do
@after_transaction_performed_on_run = true
end

before_transaction do
@before_transaction_performed_on_run = true
end

transitions :to => :running, :from => :sleeping
end

event :sleep do
after_commit do |name|
change_name_on_sleep name
end
transitions :to => :sleeping, :from => :running
end

event :fail do
after_transaction do
@after_transaction_performed_on_fail = true
end

before_transaction do
@before_transaction_performed_on_fail = true
end

transitions :to => :failed, :from => [:sleeping, :running]
end
end
Expand Down
32 changes: 32 additions & 0 deletions spec/unit/persistence/active_record_persistence_spec.rb
Expand Up @@ -468,7 +468,39 @@
expect(validator).to be_running
expect(validator.name).to eq("name")
end
end

describe 'before and after transaction callbacks' do
[:after, :before].each do |event_type|
describe "before_transaction callback" do
it "should fire :#{event_type}_transaction if transaction was successful" do
validator = Validator.create(:name => 'name')
expect(validator).to be_sleeping

expect { validator.run! }.to change { validator.send("#{event_type}_transaction_performed_on_run") }.from(nil).to(true)
expect(validator).to be_running
end

it "should fire :before_transaction if transaction failed" do
validator = Validator.create(:name => 'name')
expect do
begin
validator.fail!
rescue => ignored
end
end.to change { validator.send("#{event_type}_transaction_performed_on_fail") }.from(nil).to(true)
expect(validator).to_not be_running
end

it "should not fire if not saving" do
validator = Validator.create(:name => 'name')
expect(validator).to be_sleeping
expect { validator.run }.to_not change { validator.send("#{event_type}_transaction_performed_on_run") }
expect(validator).to be_running
expect(validator.name).to eq("name")
end
end
end
end

context "when not persisting" do
Expand Down

0 comments on commit 5e1a30e

Please sign in to comment.