Ruby on rails 导轨-用户按下';背面';创建对象后,创建重复项
我遇到一个问题,当用户填写我的评估表时,单击“创建”,然后单击浏览器的“后退”按钮,进行一些编辑,然后再次单击“创建”,它将创建重复的评估 防止类似情况发生的最佳方法是什么 创建时,每个Ruby on rails 导轨-用户按下';背面';创建对象后,创建重复项,ruby-on-rails,ruby-on-rails-3,browser,duplicates,back-button,Ruby On Rails,Ruby On Rails 3,Browser,Duplicates,Back Button,我遇到一个问题,当用户填写我的评估表时,单击“创建”,然后单击浏览器的“后退”按钮,进行一些编辑,然后再次单击“创建”,它将创建重复的评估 防止类似情况发生的最佳方法是什么 创建时,每个调查标准只能有一个评估。我不希望用户在点击后退按钮、用新内容填写表单并再次单击“创建”后丢失他们输入的任何数据 更新 routes.rb resources :survey_criteria do resources :groups do resources :evaluations end en
调查标准
只能有一个评估
。我不希望用户在点击后退按钮、用新内容填写表单并再次单击“创建”后丢失他们输入的任何数据
更新
routes.rb
resources :survey_criteria do
resources :groups do
resources :evaluations
end
end
调查标准.rb
has_many :evaluations
evaluation.rb
belongs_to :survey_criterion
belongs_to :group
有更复杂的关联,但我要寻找的答案更多,“当用户按下“后退”按钮,修改表单,然后再次单击“创建”时,如何处理它”
我希望它更新我认为在这个实例中自动创建的一个,而不是向用户抛出错误。我知道我可以添加一个会出错的验证,但我想这对用户来说是不可见的
想法?在您的评估模型中,添加以下行:
validates_uniqueness_of :survey_criterion_id
这是假设SurveyCriterion持有与您的评估相关联的外键。最简单的解决方案是更改
create
操作,该操作应与以下伪代码类似:
def create
# ...
if evaluation_exists?
update_evaluation(params[:evaluation])
else
create_evaluation(params[:evaluation])
end
# ...
end
至于你的问题“当用户按下“后退”按钮,修改表单,然后再次单击“创建”时,如何处理它”,然后我使用一些随机标记(一个短字符串)作为表单中的隐藏字段
当create请求到来时,我检查这个令牌是否已经存储在会话中。如果不是,则创建对象,并将该标记添加到已使用标记的列表中。如果令牌已经存在于会话中,我知道用户刚刚重新提交了表单,我可以相应地采取行动。通常我问他是否应该创建另一个对象。在会话中,我存储的令牌通常不超过3-5个
它看起来像这样(是的,这只是一个例子):
def创建
令牌=参数[:令牌]
会话[:令牌]| |=[]
如果会话[:令牌]。是否包括?代币
再次呈现表单(“您已经创建了对象。要另一个吗?”)
其他的
创建\u对象
session[:tokens]一种不那么优雅但更通用的方法是使用history.pushState
。在创建后的页面上:
$(function(){
if(history.pushState){
window.onpopstate = function(event){
if(window.history.state && window.history.state.previousStep){
window.location = window.history.state.previousStep;
}
}
window.history.replaceState({ previousStep: '#{edit_resource_url(resource)}'}, document.title, window.location);
window.history.pushState({}, document.title, window.location);
}
})
本例使用HTML5的历史API
。类似的事情也可以通过使用项目进行回退来完成。您还可以做两件事:
阻止浏览器缓存
使用:Disable_with=>“Processing”选项禁用创建按钮
这里也讨论了这一点:您能否更具体地说明这两个模型之间关系的性质?关于你的创建
操作,我明天上班时会尝试添加更多信息。谢谢。有关于你的表格的信息也可能有用。您是创建关联的评估
以及新的调查标准
(以嵌套形式),还是以不同的形式创建两者?如果我很了解您想要实现的目标,a应该可以做到这一点,因为点击后退按钮将返回新的调查标准
表单,确保如果再次点击提交,您将尝试创建新的调查标准
,而不是新的评估,它可能比这更复杂一点。我明天回去工作时再谈这个问题。谢谢。谢谢你花时间回答这个问题,它真的帮助我思考这个问题,应该可以满足我的需要。我认为如果有人在创建表单上使用后退按钮,他应该期望每次都创建一个新对象,这只是常识。另一方面,我承认@Arsen7的解决方案对用户更友好。我认为如果有人在他们的创建表单中输入了一个错误,很快就回击了,但没有意识到,修复了他们的输入错误,然后再次单击“创建”,这对他们来说不是“常识”。他们只会感到困惑,为什么它没有做到他们想要的。用户和常识并不完全混合:)这在你所有的控制器中都会很好。
$(function(){
if(history.pushState){
window.onpopstate = function(event){
if(window.history.state && window.history.state.previousStep){
window.location = window.history.state.previousStep;
}
}
window.history.replaceState({ previousStep: '#{edit_resource_url(resource)}'}, document.title, window.location);
window.history.pushState({}, document.title, window.location);
}
})