diff --git a/CHANGELOG.md b/CHANGELOG.md index ace51ae..a9b835e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,18 @@ thanks to [@ejlangev](https://github.com/ejlangev)) * **DSL change**: `after_commit` hooks are now event-based (see [issue #112](https://github.com/aasm/aasm/issues/112)) * **DSL change**: event and state callbacks have been re-ordered; state callbacks are not run anymore if any guard fails + * **DSL change**: `:on_transition` renamed to `:after` + * **DSL change**: `:on_transition` renamed to `:after` + * **DSL change**: transition `:after` binding changed (see [issue #59](https://github.com/aasm/aasm/issues/59), thanks to [@stiff](https://github.com/stiff)) ## 3.9.0 (not yet released) * deprecated old aasm_* class methods (old-style DSL), in preparation for AASM v4.0.0 +## 3.4.0 + + * allow retrieving the current event (`aasm.current_event`) (see [issue #159](https://github.com/aasm/aasm/issues/159) and [issue #168](https://github.com/aasm/aasm/issues/168)) + ## 3.3.3 * bugfix: support reloading development environment in Rails (see [issue #148](https://github.com/aasm/aasm/issues/148)) diff --git a/README.md b/README.md index 5dd3957..5f13619 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,31 @@ originating state (the from-state) and the target state (the to state), like thi end ``` +#### The current event triggered + +While running the callbacks you can easily retrieve the name of the event triggered +by using `aasm.current_event`: + +```ruby + # taken the example callback from above + def do_something + puts "triggered #{aasm.current_event}" + end +``` + +and then + +```ruby + job = Job.new + + # without bang + job.sleep # => triggered :sleep + + # with bang + job.sleep! # => triggered :sleep! +``` + + ### Guards Let's assume you want to allow particular transitions only if a defined condition is @@ -296,7 +321,6 @@ class Job < ActiveRecord::Base end ``` -<<<<<<< HEAD If you want to make sure that the _AASM_ column for storing the state is not directly assigned, configure _AASM_ to not allow direct assignment, like this: @@ -330,7 +354,6 @@ job.aasm_state # => 'sleeping' You can use [enumerations](http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html) in Rails 4.1+ for your state column: ->>>>>>> master ```ruby class Job < ActiveRecord::Base @@ -359,7 +382,6 @@ setting --- AASM auto-detects this situation and enabled enum support. If anything goes wrong, you can disable enum functionality and fall back to the default behavior by setting ```:enum``` to ```false```. ->>>>>>> master ### Sequel diff --git a/README_FROM_VERSION_3_TO_4.md b/README_FROM_VERSION_3_TO_4.md index 4a176f7..e288e71 100644 --- a/README_FROM_VERSION_3_TO_4.md +++ b/README_FROM_VERSION_3_TO_4.md @@ -11,6 +11,53 @@ all (event- and transition-based) guards are run to check whether the state call can be run or not. +### Callback `:on_transition` renamed to `:after` and changed its binding + +The transition callback `:on_transition` has been renamed to `:after` in order +to make clear it is being called (namely _after_ doing the transition). + +Furthermore, in alignment with the other callbacks, it's not receiving the object +at hand as first parameter and binds the current object to self. + +In summary, change from + +```ruby + aasm do + ... + transitions :from => :from_state, :to => :to_state, :on_transition => :do_something + ... + end + + ... + def some_other_method(arg) + ... + end + + def do_something(obj, arg1, arg2) + obj.some_other_method(arg1) + end +``` + +to + +```ruby + aasm do + ... + transitions :from => :from_state, :to => :to_state, :after => :do_something + ... + end + + ... + def some_other_method(arg) + ... + end + + def do_something(arg1, arg2) + some_other_method(arg1) # run on the object as self + end +``` + + ### `after_commit` hooks are now event-based The `after_commit` hooks have been move from the state level to the event level. diff --git a/lib/aasm/base.rb b/lib/aasm/base.rb index 625c244..9198f09 100644 --- a/lib/aasm/base.rb +++ b/lib/aasm/base.rb @@ -65,10 +65,12 @@ module AASM end @klass.send(:define_method, "#{name.to_s}!") do |*args, &block| + aasm.current_event = "#{name.to_s}!".to_sym aasm_fire_event(name, {:persist => true}, *args, &block) end @klass.send(:define_method, "#{name.to_s}") do |*args, &block| + aasm.current_event = name.to_sym aasm_fire_event(name, {:persist => false}, *args, &block) end end diff --git a/lib/aasm/instance_base.rb b/lib/aasm/instance_base.rb index deaf33f..b0ee17e 100644 --- a/lib/aasm/instance_base.rb +++ b/lib/aasm/instance_base.rb @@ -1,7 +1,7 @@ module AASM class InstanceBase - attr_accessor :from_state, :to_state + attr_accessor :from_state, :to_state, :current_event def initialize(instance) @instance = instance diff --git a/lib/aasm/transition.rb b/lib/aasm/transition.rb index 4f80399..a8eddb2 100644 --- a/lib/aasm/transition.rb +++ b/lib/aasm/transition.rb @@ -13,7 +13,8 @@ module AASM warn '[DEPRECATION] :on_transition is deprecated, use :after instead' opts[:after] = Array(opts[:after]) + Array(opts[:on_transition]) end - @after = opts[:after] + @after = Array(opts[:after]) + @after = @after[0] if @after.size == 1 @opts = opts end diff --git a/lib/aasm/version.rb b/lib/aasm/version.rb index b5df3af..5e55fd7 100644 --- a/lib/aasm/version.rb +++ b/lib/aasm/version.rb @@ -1,3 +1,3 @@ module AASM - VERSION = "3.3.3" + VERSION = "3.4.0" end diff --git a/spec/models/callback_new_dsl.rb b/spec/models/callback_new_dsl.rb index 5f28d41..96d630a 100644 --- a/spec/models/callback_new_dsl.rb +++ b/spec/models/callback_new_dsl.rb @@ -24,7 +24,7 @@ class CallbackNewDsl :after_exit => :after_exit_closed event :close, :before => :before, :after => :after, :guard => :event_guard do - transitions :to => :closed, :from => [:open], :guard => :transition_guard, :on_transition => :transitioning + transitions :to => :closed, :from => [:open], :guard => :transition_guard, :after => :transitioning end event :open, :before => :before, :after => :after do @@ -75,7 +75,7 @@ class CallbackNewDslArgs :after_exit => :after_exit_closed event :close, :before => :before, :after => :after do - transitions :to => :closed, :from => [:open], :on_transition => :transition_proc + transitions :to => :closed, :from => [:open], :after => :transition_proc end event :open, :before => :before, :after => :after do @@ -112,8 +112,8 @@ class CallbackWithStateArg state :out_to_lunch event :close, :before => :before_method, :after => :after_method do - transitions :to => :closed, :from => [:open], :on_transition => :transition_method - transitions :to => :out_to_lunch, :from => [:open], :on_transition => :transition_method2 + transitions :to => :closed, :from => [:open], :after => :transition_method + transitions :to => :out_to_lunch, :from => [:open], :after => :transition_method2 end end diff --git a/spec/models/double_definer.rb b/spec/models/double_definer.rb index e95fb01..615476c 100644 --- a/spec/models/double_definer.rb +++ b/spec/models/double_definer.rb @@ -12,7 +12,7 @@ class DoubleDefiner # simulating a reload state :finished, :before_enter => :do_enter event :finish do - transitions :from => :started, :to => :finished, :on_transition => :do_on_transition + transitions :from => :started, :to => :finished, :after => :do_on_transition end end diff --git a/spec/unit/event_spec.rb b/spec/unit/event_spec.rb index ab3e399..05555f1 100644 --- a/spec/unit/event_spec.rb +++ b/spec/unit/event_spec.rb @@ -244,6 +244,24 @@ describe 'should fire callbacks' do end end +describe 'current event' do + let(:pe) {ParametrisedEvent.new} + + it 'if no event has been triggered' do + expect(pe.aasm.current_event).to be_nil + end + + it 'if a event has been triggered' do + pe.wakeup + expect(pe.aasm.current_event).to eql :wakeup + end + + it 'if no event has been triggered' do + pe.wakeup! + expect(pe.aasm.current_event).to eql :wakeup! + end +end + describe 'parametrised events' do let(:pe) {ParametrisedEvent.new} diff --git a/spec/unit/transition_spec.rb b/spec/unit/transition_spec.rb index 655e3a8..589abea 100644 --- a/spec/unit/transition_spec.rb +++ b/spec/unit/transition_spec.rb @@ -237,7 +237,7 @@ describe AASM::Transition, '- when executing the transition with an :after metho end it 'should allow accessing the from_state and the to_state' do - opts = {:from => 'foo', :to => 'bar', :on_transition => :test} + opts = {:from => 'foo', :to => 'bar', :after => :test} transition = AASM::Transition.new(opts) args = {:arg1 => '1', :arg2 => '2'} obj = double('object', :aasm => AASM::InstanceBase.new('object')) @@ -248,7 +248,7 @@ describe AASM::Transition, '- when executing the transition with an :after metho return_value = transition.execute(obj, args) - expect(return_value).to eq(['from: foo to: bar']) + expect(return_value).to eq('from: foo to: bar') end end