Skip to content

Instantly share code, notes, and snippets.

@GertThiel
Created November 19, 2012 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GertThiel/4110320 to your computer and use it in GitHub Desktop.
Save GertThiel/4110320 to your computer and use it in GitHub Desktop.
Hobo::Model::Lifecycles::Transition is probably buggy
# Consider a program managing tasks, each reservable by an author and a reviewer.
# The author and the reviewer of one task must not be the same
#
transition :reserve, { :available => :reserved }, :available_to => :users,
:user_becomes => :author,
:if => Proc.new { |task| task.acting_user != task.reviewer }
Hobo::Model::Lifecycles::Transition.class_eval do
def run!(record, user, attributes)
current_state = record.lifecycle.state_name
unless start_states.include?(current_state)
raise Hobo::Model::Lifecycles::LifecycleError, "Transition #{record.class}##{name} cannot be run from the '#{current_state}' state"
end
ActiveRecord::Base.transaction do # <--- I enclosed the transition to
record.lifecycle.active_step = self # avoid incomplete runs
record.with_acting_user(user) do
# <------------------------------------ I moved `prepare!(record, attributes)` from outside of
if can_run?(record) # this `if can_run?(record)` check to it's true execution path
prepare!(record, attributes) # because `prepare!` updates a critical attribute if the
if change_state(record) # transition demands e.g. `:user_becomes => :author` what could
fire_event(record, on_transition) # interfere with guards like `author.nil?`. If such thing would
end # happen, the transition would raise a Hobo::PermissionDeniedError
else # exception.
raise Hobo::PermissionDeniedError
end
end
end # transaction
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment