= save_or_raise This plugin includes one new method for ActiveRecord::Base called save_or_raise which does almost the same thing as ActiveRecord::Base#save! but in a more readable way. == Installation gem install ryanlowe-save_or_raise --source http://gems.github.com/ == save vs save! The ActiveRecord::Base save method returns true if the model save is successful and false if it is not successful. The save! method returns true if the model save is successful and raises an exception if it is not successful. == utility The save method is useful for control flow in cases where a failed save can be handled gracefully: if model.save ... else ... end Sometimes the control flow - often within or called by a controller - cannot handle an unsuccessful save gracefully. The programmer's choices are: 1. Do not branch on the save call and ignore failures. 2. Throw an exception: raise "Save failed!" unless model.save 3. Call save! which does the same as 2 The exception thrown by 2 and 3 will generate a 500 HTTP code for the user in production but it will also notify an admin by email when used in combination with a plugin like exception_notification. Result of choice 1 is possible data corruption and invalid application state. So doing 1 is just not a good idea! == The problem with save! ...is that is poorly named. Ruby methods that end with an exclamation point are a signal that they change the object they operate on. An irb example: >> a = " hello " => " hello " >> b = a.strip! => "hello" >> a => "hello" The method strip! returns the result to b but also changes a. The save! method does not change the ActiveRecord model it is called on any more than the save method does. Also the name save! does not hint that it throws an exception in the failure case. Both of these things make the code that uses save! less readable. == Solution This plugin implements a new ActiveRecord#Base method save_or_raise(raiseable = ActiveRecord::RecordNotSaved) which can be used the following ways: model.save_or_raise # instead of model.save! model.save_or_raise "Unrecoverable save error" # raises RuntimeError with this message on failure model.save_or_raise CustomException # raises CustomException on failure In all three cases the raised exception presents a 500 HTTP error to the user in production if the save fails. The save! method remains untouched and can still be used. == Java Exceptions Java is the first programming language I used in production it and gave me the idea for this plugin. The parallel idea in the Java universe is outlined in Item 40 of Joshua Bloch's book Effective Java: "Use checked exceptions for recoverable conditions and run-time exceptions for programming errors". Java checked exceptions can be caught and handled gracefully and the program can continue. Java run-time (or unchecked) exceptions should not be caught by the Java VM and allowed to bubble to the top of the call stack, where they will make the program fail.
Project
ryanlowe-save_or_raise
A replacement for ActiveRecord::Base#save! for Ruby on Rails
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
Development
Dependencies
Runtime
> 2.0.0
Project Readme