Skip to content

Instantly share code, notes, and snippets.

@saikumar-everest
Created July 7, 2021 08:23
Show Gist options
  • Save saikumar-everest/7dd7da7d709c5f80a871cba990f09854 to your computer and use it in GitHub Desktop.
Save saikumar-everest/7dd7da7d709c5f80a871cba990f09854 to your computer and use it in GitHub Desktop.
for debug purpose
class StateEventFactory
class ValidationError < RuntimeError
def initialize(message, state_event)
@state_event = state_event
super(message)
end
def exception_meta_data
{ :state_event => @state_event }
end
end
include ActiveModel::Model
attr_writer :machine_klass, :actor
attr_reader :object, :actor, :actor_ip
attr_accessor :state_event
# All these things are required, all the time.
validates :object, :actor, :presence => true
validate :validate_event_can_be_performed
delegate :state, :performable_events, :to => :machine
def self.can_perform?(object, actor, event)
build(object, actor, nil).performable_events.include? event
end
def self.build(object, actor, actor_ip = nil, params = {})
new(object, actor, actor_ip, params)
end
def self.create(object, actor, actor_ip = nil, params = {})
build(object, actor, actor_ip, params).tap do |event|
event.save
end
end
def self.create!(object, actor, actor_ip = nil, params = {})
build(object, actor, actor_ip, params).tap do |event|
raise ValidationError.new("Validation failed: #{event.error_messages}", self) unless event.save
end
end
def initialize(object, actor, actor_ip = nil, attrs = {})
@object = object
@actor = actor
@actor_ip = actor_ip
@machine_klass = default_machine_klass
(attrs || {}).each { |k, v| public_send("#{k}=", v) }
end
def machine
# Allows us to inject a different machine class for testing
@machine ||= @machine_klass.new(object, self)
end
def save
valid? && machine.fire_events(state_event)
end
def error_messages
errors.values.flatten.to_sentence
end
def persisted?
false
end
def cannot_perform?(state_event)
!can_perform?(state_event)
end
def can_perform?(event_name)
p "state_event", state_event.to_s
p "performable_events", performable_events
p "performable_events.size", performable_events.size
p performable_events.map(&:to_s)
performable_events.map(&:to_s).include?(state_event.to_s)
end
private
# We could memoize this. If the current class is Job::EventFactory, it will
# look for a Job::Machine class.
def default_machine_klass
namespace = self.class.name.deconstantize
machine_klass = "#{namespace}::Machine"
machine_klass.constantize
end
def validate_event_can_be_performed
if object && cannot_perform?(state_event)
errors.add :base, :event_doesnt_exist
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment