rails_state_machine 3.0.0 released

Updated . Posted . Visible to the public. Auto-destruct in 58 days

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 a TransitionNotFoundError error.
  • Changed: Calling <event_name> with an invalid event adds an error to the <state_name>_event attribute instead of raising a TransitionNotFoundError error.
  • Changed: Calling <event_name>! with an invalid event adds an error to the <state_name>_event attribute and raises a ActiveRecord::RecordInvalid error instead of a TransitionNotFoundError error.
  • Changed: The <state_name>_event type was changed to ActiveModel::Attributes.
  • Changed: #find_event returns nil in case the event is missing, previously it raised a KeyError error.
  • Changed: The transition of a <state_name>_event is executed in a prepended before_validation callback. If the transition is possible, the <state_attribute> is changed and the <state_name>_event is set to nil 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
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Emanuel to makandra dev (2024-06-24 06:02)