Skip to content

Instantly share code, notes, and snippets.

@matismasters
Created November 13, 2012 18:30
Show Gist options
  • Save matismasters/4067507 to your computer and use it in GitHub Desktop.
Save matismasters/4067507 to your computer and use it in GitHub Desktop.
Example of state machine usage
state_machine :initial => :unassigned do
after_transition :on => [:accept, :assign], :do => :save
# Reject
event :reject do
transition :assigned => :unassigned
end
after_transition :on => :reject do
self.teacher.add_rejected_petition(self)
self.teacher = nil
self.save
end
# Assign
event :assign do
transition [:unassigned, :rejected] => :assigned
end
after_transition :on => :assign do |transition|
schedule_review_notification_for(self.teacher)
send_transactional_mail(:petition_awaiting_review_notification, self.applicant)
end
# Accept
event :accept do
transition [:assigned] => :waiting_for_payment, :unless => lambda {|petition| petition.paid }
transition [:assigned] => :active, :if => lambda {|petition| petition.paid }
end
after_transition :on => :accept do |transition|
send_transactional_mail(:payment_information, self.applicant)
end
# Issue payment
event :issue_payment do
transition [:waiting_for_payment] => :active, :if => lambda {|petition| !petition.paid && petition.applicant.has_payment_data? }
end
before_transition :on => :issue_payment do |transition|
charge_id = self.applicant.charge(self.price)
if charge_id
self.paid = true
self.stripe_charge_id = charge_id
else
send_transactional_mail(:unsuccessful_charge, self.applicant, self)
false
end
end
after_transition :on => :issue_payment do
send_transactional_mail(:you_have_been_charged, self.applicant, self)
send_transactional_mail(:applicant_has_paid, self.teacher, self)
end
# Deliver
event :deliver do
transition :active => :delivered
end
after_transition :on => :deliver do
send_transactional_mail(:teacher_delivered_petition, self.applicant, self)
end
# Continue working
event :continue_working do
transition [:delivered] => :active
end
after_transition :on => :continue_working do
send_transactional_mail(:continue_working_on_petition, self.teacher, self)
end
# Approve
event :approve do
transition :delivered => :approved
end
after_transition :on => :approve do
send_transactional_mail(:applicant_approved_petition, self.teacher, self)
create_teacher_payment(self.stripe_charge_id)
end
# Mark as conflicting
event :mark_as_conflicting do
transition [:active, :delivered] => :conflicting
end
after_transition :on => :mark_as_conflicting do
[self.teacher,self.applicant].each do |user|
send_transactional_mail(:conflict_will_be_solved, user, self)
end
Admin.emails.each do |email_address|
send_transactional_mail(:petition_marked_as_conflicting, email_address, self)
end
end
# Force approve
event :force_approve do
transition :conflicting => :approved
end
after_transition :on => :force_approve do
[self.teacher,self.applicant].each do |user|
send_transactional_mail(:forced_approval, user, self)
end
create_teacher_payment(self.stripe_charge_id)
end
# Solve conflict
event :solve_conflict do
transition :conflicting => :active
end
after_transition :on => :solve_conflict do
self.participants.each do |participant|
send_transactional_mail(:admin_solved_conflict, participant, self)
end
end
# Refund
event :refund do
transition [:active, :conflicting] => :refunded, :if => lambda {|petition| petition.paid }
end
before_transition :on => :refund do |transition|
if self.applicant.refund(self.stripe_charge_id)
self.paid = false
self.stripe_charge_id = nil
true
else
false
end
end
after_transition :on => :refund do |transition|
send_transactional_mail(:refunded_notification, self.applicant)
send_transactional_mail(:petition_has_been_closed, self.teacher)
end
end
def schedule_review_notification_for(teacher)
if teacher == self.teacher # This could change until this method gets called
send_transactional_mail(:review_notification, teacher, self)
delay(:run_at => Time.now + 24*60*60).schedule_review_notification_for(teacher)
end
end
# Add subsets for each state in the state machine
state_machine.states.map(&:name).each do |name|
subset(name, :state => name.to_s)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment