Module: Sequel::Plugins::StateMachine::InstanceMethods
- Defined in:
- lib/sequel/plugins/state_machine.rb
Instance Method Summary collapse
- #_state_value_attr ⇒ Object
- #audit(message, reason: nil) ⇒ Object
- #audit_one_off(event, messages, reason: nil) ⇒ Object
- #commit_audit_log(transition) ⇒ Object
- #current_audit_log ⇒ Object
-
#must_process(event, *args) ⇒ Object
Same as process, but raises an error if the transition fails.
- #new_audit_log ⇒ Object
-
#process(event, *args) ⇒ Object
Send event with arguments inside of a transaction, save the changes to the receiver, and return the transition result.
-
#process_if(event, *args) ⇒ Object
Same as must_process, but takes a lock, and calls the given block, only doing actual processing if the block returns true.
-
#valid_state_path_through?(event) ⇒ Boolean
Return true if the given event can be transitioned into by the current state.
- #validates_state_machine ⇒ Object
Instance Method Details
#_state_value_attr ⇒ Object
127 128 129 |
# File 'lib/sequel/plugins/state_machine.rb', line 127 def _state_value_attr return @_state_value_attr ||= self.class.state_machine.attribute end |
#audit(message, reason: nil) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/sequel/plugins/state_machine.rb', line 57 def audit(, reason: nil) audlog = self.current_audit_log if audlog.class. audlog. ||= [] audlog. << else audlog. ||= "" audlog. += (audlog..empty? ? : ( + "\n")) end audlog.reason = reason if reason end |
#audit_one_off(event, messages, reason: nil) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/sequel/plugins/state_machine.rb', line 69 def audit_one_off(event, , reason: nil) = [] unless .respond_to?(:to_ary) audlog = self.new_audit_log audlog.set( at: Time.now, event: event, from_state: self.status, to_state: self.status, messages: audlog.class. ? : .join("\n"), reason: reason || "", actor: StateMachines::Sequel.current_actor, ) self.add_audit_log(audlog) end |
#commit_audit_log(transition) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/sequel/plugins/state_machine.rb', line 26 def commit_audit_log(transition) StateMachines::Sequel.log(self, :debug, "committing_audit_log", {transition: transition}) current = self.current_audit_log last_saved = self.audit_logs.find do |a| a.event == transition.event.to_s && a.from_state == transition.from && a.to_state == transition.to end if last_saved StateMachines::Sequel.log(self, :debug, "updating_audit_log", {audit_log_id: last_saved.id}) last_saved.update( at: Time.now, actor: StateMachines::Sequel.current_actor, messages: current., reason: current.reason, ) else StateMachines::Sequel.log(self, :debug, "creating_audit_log", {}) current.set( at: Time.now, actor: StateMachines::Sequel.current_actor, event: transition.event.to_s, from_state: transition.from, to_state: transition.to, ) self.add_audit_log(current) end @current_audit_log = nil end |
#current_audit_log ⇒ Object
17 18 19 20 21 22 23 24 |
# File 'lib/sequel/plugins/state_machine.rb', line 17 def current_audit_log if @current_audit_log.nil? StateMachines::Sequel.log(self, :debug, "preparing_audit_log", {}) @current_audit_log = self.new_audit_log @current_audit_log.reason = "" end return @current_audit_log end |
#must_process(event, *args) ⇒ Object
Same as process, but raises an error if the transition fails.
97 98 99 100 101 |
# File 'lib/sequel/plugins/state_machine.rb', line 97 def must_process(event, *args) success = self.process(event, *args) raise StateMachines::Sequel::FailedTransition.new(self, event) unless success return self end |
#new_audit_log ⇒ Object
11 12 13 14 15 |
# File 'lib/sequel/plugins/state_machine.rb', line 11 def new_audit_log audit_log_assoc = self.class.association_reflections[:audit_logs] model = Kernel.const_get(audit_log_assoc[:class_name]) return model.new end |
#process(event, *args) ⇒ Object
Send event with arguments inside of a transaction, save the changes to the receiver, and return the transition result. Used to ensure the event processing happens in a transaction and the receiver is saved.
87 88 89 90 91 92 93 94 |
# File 'lib/sequel/plugins/state_machine.rb', line 87 def process(event, *args) self.db.transaction do self.lock! result = self.send(event, *args) self.save_changes return result end end |
#process_if(event, *args) ⇒ Object
Same as must_process, but takes a lock, and calls the given block, only doing actual processing if the block returns true. If the block returns false, it acts as a success. Used to avoid issues concurrently processing the same object through the same state.
107 108 109 110 111 112 113 |
# File 'lib/sequel/plugins/state_machine.rb', line 107 def process_if(event, *args) self.db.transaction do self.lock! return self unless yield(self) return self.must_process(event, *args) end end |
#valid_state_path_through?(event) ⇒ Boolean
Return true if the given event can be transitioned into by the current state.
116 117 118 119 120 121 122 123 124 125 |
# File 'lib/sequel/plugins/state_machine.rb', line 116 def valid_state_path_through?(event) current_state = self.send(self._state_value_attr).to_sym event_obj = self.class.state_machine.events[event] or raise "Invalid event #{event}" event_obj.branches.each do |branch| branch.state_requirements.each do |state_req| return true if state_req[:from]&.matches?(current_state) end end return false end |
#validates_state_machine ⇒ Object
131 132 133 134 135 136 |
# File 'lib/sequel/plugins/state_machine.rb', line 131 def validates_state_machine states = self.class.state_machine.states.map(&:value) state = self[self._state_value_attr] return if states.include?(state) self.errors.add(self._state_value_attr, "status '#{state}' must be one of (#{states.sort.join(', ')})") end |