Rails: Workflow: Model implements State Machine
StateMachine is a gem that provides all the behavior necessary to implement workflow on your Model. Need an event that once it occurs on an instance on your Model will trigger an email? Or perhaps you need to access a REST service for verification once one of the instance’s fields is modified. Here is a sample suite where events and state transitions are set up for a Model to support workflow.
class MyModel < ActiveRecord::Base
state_machine :status, :initial => :new do
before_transition :on => :preapprove do |my_model|
User.current ? user_id = User.current.id : user_id = 1
@user = User.find_by(:id => user_id)
log_entry = Approval.new(:approvable_type => 'MyModel',
:approvable_id => my_model.id,
:approved_by_user_id => user_id,
:approved_at => Time.now,
:event => 'preapprove',
:state => '')
unless @user.blank? || @user.permanent_users.blank?
log_entry.permanent_user_id = @user.permanent_users.first.id
end
log_entry.save!
end
before_transition :on => :approve do |my_model|
User.current ? user_id = User.current.id : user_id = 1
@user = User.find_by(:id => user_id)
log_entry = Approval.new(:approvable_type => 'MyModel',
:approvable_id => my_model.id,
:approved_by_user_id => user_id,
:approved_at => Time.now,
:event => 'approve',
:state => '')
unless @user.blank? || @user.permanent_users.blank?
log_entry.permanent_user_id = @user.permanent_users.first.id
end
log_entry.save!
end
before_transition :on => :decline do |my_model|
User.current ? user_id = User.current.id : user_id = 1
@user = User.find_by(:id => user_id)
log_entry = Approval.new(:approvable_type => 'MyModel',
:approvable_id => my_model.id,
:approved_by_user_id => user_id,
:approved_at => Time.now,
:event => 'decline',
:state => '')
unless @user.blank? || @user.permanent_users.blank?
log_entry.permanent_user_id = @user.permanent_users.first.id
end
log_entry.save!
end
after_transition :to => :preapproved do |my_model|
my_model.approval_fields_required = true
end
after_transition :to => :contracted do |my_model|
my_model.create_company_from_application
my_model.create_user_from_application
my_model.delay.notify_account_manager
company = Company.tenant_companies.where(my_model: my_model.id).first
end
after_transition :to => :declined do |my_model|
PartnerPathMailer.deliver("enrollment_vendor_declined", [my_model])
end
after_transition :to => :approved do |my_model|
PartnerPathMailer.deliver("enrollment_vendor_approved", [my_model])
end
after_transition :to => :partner_declined do |my_model|
PartnerPathMailer.deliver("enrollment_partner_declined", [my_model])
end
event :preapprove do
transition :new => :preapproved
end
event :approve do
transition :new => :approved
transition :preapproved => :approved
transition :change_requested => :approved
end
event :request_change do
transition :approved => :change_requested
end
event :accept do
transition :approved => :contracted
end
event :decline do
transition :new => :declined
transition :preapproved => :declined
transition :change_requested => :declined
transition :approved => :partner_declined
end
end
end
Comment