Rails: Prevent duplicate inserts due to pressing back button and save again

After some investigations I found a suitable solution based on cookies. Here it is:

In the controller's "new" action, a timestamp with the current time is generated and rendered in the form as hidden field. When the user submits the form, this timestamps gets back to the controller's "create" action. After creating the record, this timestamp is stored in the session cookie. If the user goes back to the "new" form via browser's back button, he gets a stale form, which means its timestamp is older than the one stored in the cookie. This is checked before creating the record and results in an error message.

Here is the controller code:

def new
  @post = Post.new
  @stale_form_check_timestamp = Time.now.to_i
end

def create
  @post = Post.new(params[:post])

  if session[:last_created_at].to_i > params[:timestamp].to_i
    flash[:error] = 'This form is stale!'
    render 'new'
  else
    @post.save!
    @stale_form_check_timestamp = Time.now.to_i
    session[:last_created_at] = @stale_form_check_timestamp
  end
end

And here the form code:

- form_for @post do |f|
  = tag :input, :type => 'hidden', :name => 'timestamp', :value => @stale_form_check_timestamp
  = f.input :some_field
  = .......

When I had that same problem I created this little gem that solves it. When the user hits back, he's redirected to the edit_path of the record, instead of going back to the new_path.

https://github.com/yossi-shasho/redirect_on_back

You can do something like:

def create
  @user = User.new(params[:user])
  if result = @user.save
    redirect_on_back_to edit_user_path(@user) # If user hits 'back' he'll be redirected to edit_user_path
    redirect_to @user
  end
end