We released a new version of our
rails_state_machine
Show archive.org snapshot
gem. The release contains mainly a breaking change on how errors in state transitions are handled.
Please have a look at the changelog Show archive.org snapshot for more details and an upgrade guide:
3.0.0 2024-06-21
Breaking changes
- Changed: Setting the
<state_name>_event
to an invalid event adds an error to the attribute instead of raising aTransitionNotFoundError
error. - Changed: Calling
<event_name>
with an invalid event adds an error to the<state_name>_event
attribute instead of raising aTransitionNotFoundError
error. - Changed: Calling
<event_name>!
with an invalid event adds an error to the<state_name>_event
attribute and raises aActiveRecord::RecordInvalid
error instead of aTransitionNotFoundError
error. - Changed: The
<state_name>_event
type was changed toActiveModel::Attributes
. - Changed:
#find_event
returnsnil
in case the event is missing, previously it raised aKeyError
error. - Changed: The transition of a
<state_name>_event
is executed in a prependedbefore_validation
callback. If the transition is possible, the<state_attribute>
is changed and the<state_name>_event
is set tonil
afterwards. If the transition is not possible, the<state_attribute>
is not changed and the<state_name>_event
keeps the set value.
Before:
order.update(state_event: 'finish') # => RailsStateMachine::Event::TransitionNotFoundError
order.finish # => RailsStateMachine::Event::TransitionNotFoundError
order.finish! # => RailsStateMachine::Event::TransitionNotFoundError
After:
order.update(state_event: 'finish') # => false (state_event has the error :invalid)
order.finish # => false (state_event has the error :invalid)
order.finish! # => ActiveRecord::RecordInvalid (state_event has the error :invalid)
Upgrade examples:
# Before the upgrade you might have rescued RailsStateMachine::Event::TransitionNotFoundError in e.g. a controller
def update
build_user
if @user.save
flash[:success] = 'User saved!'
redirect_to @user
else
flash.now[:error] = 'User could not be saved!'
render(:edit, status: :unprocessable_entity)
end
rescue RailsStateMachine::Event::TransitionNotFoundError
flash.now[:error] = 'State event not valid anymore, maybe reload the page?'
render(:edit, status: :unprocessable_entity)
end
# After upgrade you can either show a flash message or show an error message in your view for the <state>_event attribute
def update
build_user
if @user.save
flash[:success] = 'User saved!'
redirect_to @user
else
flash.now[:error] = @user.errors.include?(:state_event) ? 'State event not valid anymore, maybe reload the page?' : 'User could not be saved!'
render(:edit, status: :unprocessable_entity)
end
end
Posted by Emanuel to makandra dev (2024-06-24 06:02)