module StatusWorkflow::ClassMethods
Public Instance Methods
before_status_transition(&blk)
click to toggle source
# File lib/status_workflow.rb, line 86 def before_status_transition(&blk) @before_status_transition = blk end
status_workflow(workflows)
click to toggle source
# File lib/status_workflow.rb, line 89 def status_workflow(workflows) if workflows.first.last.is_a?(Array) # default mode: use just status workflows = { nil => workflows } end workflows.each do |prefix, transitions| if prefix # no this is not a mistake, the localvar is prefix_ prefix_ = "#{prefix}_" define_method "#{prefix_}status_transition!" do |*args, &blk| status_transition!(*(args+[prefix]), &blk) end end transitions.inject({}) do |memo, (from_status, to_statuses)| to_statuses.each do |to_status| to_status = to_status.to_sym memo[to_status] ||= Set.new memo[to_status] << from_status&.to_sym # support nil or strings/symbols end memo end.each do |to_status, from_statuses| define_method "#{prefix_}enter_#{to_status}!" do send "#{prefix_}status_transition!", nil, to_status end define_method "#{prefix_}can_enter_#{to_status}?" do |raise_error = false| reload status = read_attribute "#{prefix_}status" memo = from_statuses.include? status&.to_sym if raise_error and not memo raise InvalidTransition, "can't enter #{to_status} from #{status}, expected #{from_statuses.to_a.join('/')}" end memo end define_method "#{prefix_}enter_#{to_status}_if_possible" do begin; send("#{prefix_}enter_#{to_status}!"); rescue InvalidTransition; false; end end end end end