lib/aasm/base.rb in aasm-4.8.0 vs lib/aasm/base.rb in aasm-4.9.0

- old
+ new

@@ -1,14 +1,15 @@ module AASM class Base - attr_reader :state_machine + attr_reader :klass, + :state_machine def initialize(klass, name, state_machine, options={}, &block) @klass = klass @name = name - # @state_machine = @klass.aasm(@name).state_machine + # @state_machine = klass.aasm(@name).state_machine @state_machine = state_machine @state_machine.config.column ||= (options[:column] || default_column).to_sym # @state_machine.config.column = options[:column].to_sym if options[:column] # master @options = options @@ -22,19 +23,27 @@ configure :skip_validation_on_save, false # use requires_new for nested transactions (in ActiveRecord) configure :requires_new_transaction, true + # use pessimistic locking (in ActiveRecord) + # true for FOR UPDATE lock + # string for a specific lock type i.e. FOR UPDATE NOWAIT + configure :requires_lock, false + # set to true to forbid direct assignment of aasm_state column (in ActiveRecord) configure :no_direct_assignment, false + # allow a AASM::Base sub-class to be used for state machine + configure :with_klass, AASM::Base + configure :enum, nil # make sure to raise an error if no_direct_assignment is enabled # and attribute is directly assigned though aasm_name = @name - @klass.send :define_method, "#{@state_machine.config.column}=", ->(state_name) do + klass.send :define_method, "#{@state_machine.config.column}=", ->(state_name) do if self.class.aasm(:"#{aasm_name}").state_machine.config.no_direct_assignment raise AASM::NoDirectAssignmentError.new( 'direct assignment of AASM column has been disabled (see AASM configuration for this class)' ) else @@ -61,49 +70,49 @@ end end # define a state def state(name, options={}) - @state_machine.add_state(name, @klass, options) + @state_machine.add_state(name, klass, options) - if @klass.instance_methods.include?("#{name}?") - warn "#{@klass.name}: The aasm state name #{name} is already used!" + if klass.instance_methods.include?("#{name}?") + warn "#{klass.name}: The aasm state name #{name} is already used!" end aasm_name = @name - @klass.send :define_method, "#{name}?", ->() do + klass.send :define_method, "#{name}?", ->() do aasm(:"#{aasm_name}").current_state == :"#{name}" end - unless @klass.const_defined?("STATE_#{name.upcase}") - @klass.const_set("STATE_#{name.upcase}", name) + unless klass.const_defined?("STATE_#{name.upcase}") + klass.const_set("STATE_#{name.upcase}", name) end end # define an event def event(name, options={}, &block) @state_machine.add_event(name, options, &block) - if @klass.instance_methods.include?("may_#{name}?".to_sym) - warn "#{@klass.name}: The aasm event name #{name} is already used!" + if klass.instance_methods.include?("may_#{name}?".to_sym) + warn "#{klass.name}: The aasm event name #{name} is already used!" end # an addition over standard aasm so that, before firing an event, you can ask # may_event? and get back a boolean that tells you whether the guard method # on the transition will let this happen. aasm_name = @name - @klass.send :define_method, "may_#{name}?", ->(*args) do + klass.send :define_method, "may_#{name}?", ->(*args) do aasm(:"#{aasm_name}").may_fire_event?(:"#{name}", *args) end - @klass.send :define_method, "#{name}!", ->(*args, &block) do + klass.send :define_method, "#{name}!", ->(*args, &block) do aasm(:"#{aasm_name}").current_event = :"#{name}!" aasm_fire_event(:"#{aasm_name}", :"#{name}", {:persist => true}, *args, &block) end - @klass.send :define_method, "#{name}", ->(*args, &block) do + klass.send :define_method, "#{name}", ->(*args, &block) do aasm(:"#{aasm_name}").current_event = :"#{name}" aasm_fire_event(:"#{aasm_name}", :"#{name}", {:persist => false}, *args, &block) end end @@ -143,10 +152,10 @@ @state_machine.events.values end # aasm.event(:event_name).human? def human_event_name(event) # event_name? - AASM::Localizer.new.human_event_name(@klass, event) + AASM::Localizer.new.human_event_name(klass, event) end def states_for_select states.map { |state| state.for_select } end