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