为了让我们网站中的所有内容都可以翻译(包括验证的错误消息),我们几乎将所有表单都切换到远程表单。虽然这有助于翻译错误消息的能力,但我们遇到了其他问题,例如:
有什么地方可以阅读有关远程表单最佳实践的信息吗?我该如何处理多次点击问题?将所有表单切换到远程表单是一个很大的错误吗?
最佳答案
最简单的解决方案是为每个表单生成一个 token 。然后您的 create
操作可以确保它还没有被使用,并确定是否应该创建记录。
这是我将如何编写此功能。请注意,我还没有实际测试过这个,但这个概念应该有效。
1.
在 new
操作中创建一个哈希来标识表单请求。
def new
@product = Product.new
@form_token = session["form_token"] = SecureRandom.hex(15)
end
2.
向存储表单标记的表单添加一个隐藏字段。这将在
create
操作中捕获,以确保之前没有提交过表单。<%= hidden_field_tag :form_token, @form_token %>
3.
在
create
操作中,您可以确保表单标记在 session
和 params
变量之间匹配。这将使您有机会查看这是第一次提交还是第二次提交。def create
# delete the form token if it matches
if session[:form_token] == params[:form_token]
session[:form_token] = nil
else
# if it doesn't match then check if a record was created recently
product = Product.where('created_at > ?', 3.minutes.ago).where(title: params[:product][:title]).last
# if the product exists then show it
# or just return because it is a remote form
redirect_to product and return if product.present?
end
# normal create action here ...
end
更新: 我上面描述的有一个名字,它被称为同步器(或似曾相识) token 。如 in this article 所述,是防止双重提交的正确方法。
This strategy addresses the problem of duplicate form submissions. A synchronizer token is set in a user's session and included with each form returned to the client. When that form is submitted, the synchronizer token in the form is compared to the synchronizer token in the session. The tokens should match the first time the form is submitted. If the tokens do not match, then the form submission may be disallowed and an error returned to the user. Token mismatch may occur when the user submits a form, then clicks the Back button in the browser and attempts to resubmit the same form.
On the other hand, if the two token values match, then we are confident that the flow of control is exactly as expected. At this point, the token value in the session is modified to a new value and the form submission is accepted.
关于ruby-on-rails - 我们如何规避这些远程表单的缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11040774/