Reputation: 1168
I am having an issue with my Rails app, that if a user clicks submits on a form, then stops the browser from proceeding (KILL_CURSOR), if they resubmit the form it will create a duplicate entry in the database. I've tried installing javascript to disable input after submit, but it doesn't work in this use case.
Is there a way for me to validate whether a form is a resubmit even it it has the same authenticity token?
Here is my controller:
def create
@location = Location.new(params[:location])
@location.user_id = current_user.id
if @location.save
#refresh window to show new location
render :js => "window.location.reload();"
#check that form fields have been completed properly
else
respond_to do |format|
format.js
end
end
Upvotes: 0
Views: 328
Reputation: 381
First, it is a good idea to disable the submit button using javascript. Not only this meets your need, but also it gives users a good feedback of their actions. But you can't rely on that, because the javascript might be disabled in web browser.
You could check the database to see whether there's already a duplicated document before inserting a new one. The point is that the definition of duplication is based on your business logic. For example, two requests about the same location from the same user in 5 minutes are duplicated. However, in extreme cases, two or more concurrent requests may lead to duplicated documents, because they may check the database at the same time, seeing nothing, then insert.
In the database layer, unique index
in MongoDB could be helpful if some fields of data themselves defines the duplication and should be unique. For example, a given user at a given location should occur at most once in database. Building a unique index (user_id, location._id)
can guarantee that constrain.
db.collection.ensureIndex( { user_id: 1, location._id: 1 }, { unique: true } )
Note unique index is not allowed in sharding unless it is the shard key. Because there is no easy way to guarantee that among many machines, if it's not the shard key.
Upvotes: 1