It's actually much easier than you'd think, within application.rb I've got the following:
class ApplicationController < ActionController::Base before_filter :catch_cancel, :update => [:create, :update, :destroy] after_filter :set_referrer, :only => [:index, :show] private def set_referrer session[:referrer] = url_for(params) end def catch_cancel redirect_to session[:referrer] if params[:commit] == "Cancel" end end
The logic being, that if we've got a fully RESTful architecture the only pages we'll ever want to go "back" will be the index or show actions on each controller. So we cheekily call url_for in an after filter with the current params to get the path of the page we've just display the user, and stash it in the session. Theoretically it may be possible to use ENV["HTTP_REFERER"] instead but it's not guaranteed, this approach however ensures we keep track of the page to go back to explicitly ourselves.
Then, to piece it all together there's a before filter checking if the user has clicked the submit button labeled with "Cancel". You'll need to change that equality test dependent on what text you put on your button. You may also need to move the before filter into the controllers that require them, depending on the order it needs to run with other filters you have.
Hope that helps.