ruby-on-railsruby

What exactly does "ensure raise ActiveRecord::Rollback" do?


I was reading what an around_action does:

begin
    # Do before action...
    logger.info 'I am the before action'

    # Do the action, which is passed as a block to your "around filter"
    # Note that if you were to delete this line, the action will never be called!
    yield

    # Do after action...
    logger.info 'I am the after action'
ensure
    raise ActiveRecord::Rollback
end

and I understand the example up until

ensure
    raise ActiveRecord::Rollback

What does ensure raise ActiveRecord::Rollback do exactly?

Note: a similar convention is used in the rails guides, although I think it must be assumed knowledge because the guide doesn't provide a direct explanation either


Solution

  • The code in ensure is always run even if the begin section raises an unrescued exception.

    begin
      puts "Hello"
      raise "Oh noes!"
    ensure
      puts "World!"
    end
    
    max@pop-os ~/p/playground> ruby runme.rb
    Hello
    World!
    Traceback (most recent call last):
    runme.rb:3:in `<main>': Oh noes! (RuntimeError)
    

    Note the order here - the ensure section is executed before the execution is halted by the exception.

    Thats why its used for things like closing file handlers, connections or rolling back transactions which otherwise could leave the system unstable or tie up resources.

    In that particular example they are hinting on how you could preview the state change caused by an action and then undo it by always performing a rollback - even if an unexpected exception occurs.