Last active
August 25, 2016 17:15
-
-
Save jgarth/cc687ee77236bcfd2227023ad7b02c76 to your computer and use it in GitHub Desktop.
AASM Transitional Hooks DSL / Spec / Implementation / Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
describe 'AASM hooks' do | |
class Foo | |
include AASM | |
include Concerns::TriggersHooksAfterAASMStateChanges | |
aasm do | |
state :pending, initial: true # waiting for manual review | |
state :reviewed # either manual or auto; waiting for arrive, could be in transit | |
event :review do | |
transitions from: :pending, to: :reviewed | |
end | |
end | |
def vendors | |
return [FooVendor] | |
end | |
end | |
class FooVendor | |
include Concerns::DefinesHooksForAASMStateChanges | |
register_transition_hook klass: Foo, from_state: :pending, to_state: :reviewed do | |
raise 'FooTransitionHookCalled' | |
end | |
end | |
describe 'Vendor objects' do | |
it 'can register hooks' do | |
expect(FooVendor.aasm_state_change_hooks).to_not be_blank | |
end | |
end | |
describe 'Hook-calling objects' do | |
it 'asks all vendors for hooks' do | |
allow(FooVendor).to receive(:aasm_state_change_hooks).and_call_original | |
foo = Foo.new() | |
expect do | |
foo.review! | |
end.to raise_error('FooTransitionHookCalled') | |
expect(FooVendor).to have_received(:aasm_state_change_hooks) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Concerns::DefinesHooksForAASMStateChanges | |
extend ActiveSupport::Concern | |
included do | |
class << self | |
attr_reader :aasm_state_change_hooks | |
def register_transition_hook(klass:, from_state:, to_state:, &block) | |
@aasm_state_change_hooks ||= [] | |
@aasm_state_change_hooks << { klass: klass, from_state: from_state, | |
to_state: to_state, block: block } | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Concerns::TriggersHooksAfterAASMStateChanges | |
extend ActiveSupport::Concern | |
included do | |
aasm do | |
after_all_transitions :trigger_hooks | |
end | |
def vendors | |
[] | |
end | |
end | |
private | |
def trigger_hooks | |
hooks = vendors.flat_map { |v| v.aasm_state_change_hooks }.compact.uniq | |
hooks.select do |hook| | |
hook[:klass] === self && | |
(hook[:from_state] == aasm.from_state || hook[:from_state].blank?) && | |
hook[:to_state] == aasm.to_state | |
end.each do |hook| | |
hook[:block].call(self) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment