我的Rails应用程序出现问题,如果用户点击表单上的提交,则停止浏览器继续(KILL_CURSOR),如果他们重新提交表单,则会在数据库中创建重复的条目。我已经尝试在提交后安装javascript来禁用输入,但它在这个用例中不起作用。
我是否有办法验证表单是否重新提交,即使它具有相同的真实性令牌?
这是我的控制器:
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
答案 0 :(得分:1)
首先,使用javascript禁用提交按钮是个好主意。这不仅满足了您的需求,而且还为用户提供了良好的行动反馈。但你不能依赖它,因为可能在网络浏览器中禁用了javascript。
在插入新文档之前,您可以检查数据库以查看是否已存在重复文档。重点是复制的定义基于您的业务逻辑。例如,在5分钟内来自同一用户的两个相同位置的请求被复制。但是,在极端情况下,两个或多个并发请求可能会导致重复文档,因为它们可能同时检查数据库,什么也看不见,然后插入。
在数据库层中,如果某些数据字段本身定义了重复并且应该是唯一的,那么MongoDB中的unique index
可能会有所帮助。例如,给定位置的给定用户最多应在数据库中出现一次。构建唯一索引(user_id, location._id)
可以保证约束。
db.collection.ensureIndex( { user_id: 1, location._id: 1 }, { unique: true } )
注意除非是分片键,否则分片中不允许使用唯一索引。因为没有简单的方法来保证在许多机器中,如果它不是分片键。