ruby-on-rails - 我们如何规避这些远程表单的缺点?

标签 ruby-on-rails ajax remote-forms

为了让我们网站中的所有内容都可以翻译(包括验证的错误消息),我们几乎将所有表单都切换到远程表单。虽然这有助于翻译错误消息的能力,但我们遇到了其他问题,例如:

  • 如果用户多次单击提交按钮,则该操作会被多次调用。如果我们有一个用于在数据库中创建新记录的远程表单,并假设用户的数据有效,则每次点击都会添加一个新对象(具有完全相同的内容)。有没有办法确保这样的事情不会发生?

  • 有什么地方可以阅读有关远程表单最佳实践的信息吗?我该如何处理多次点击问题?将所有表单切换到远程表单是一个很大的错误吗?

    最佳答案

    最简单的解决方案是为每个表单生成一个 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 操作中,您可以确保表单标记在 sessionparams 变量之间匹配。这将使您有机会查看这是第一次提交还是第二次提交。
    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/

    相关文章:

    ruby-on-rails - Ruby on Rails : How do I get rid of the ActiveRecord:ReadOnlyRecord error?

    ruby-on-rails - stub_chain 和 should_receive

    javascript - 菜单仅淡入某个类的 div 并隐藏其他 div

    javascript - 像 pat-pickadate 这样的 Plone5 Mockup 小部件不适用于动态生成的内容

    javascript - ajax调用成功的for循环不起作用

    ruby-on-rails - rails : submit (via AJAX) when drop-down option clicked

    ruby-on-rails - rspec 中的上下文

    ruby-on-rails - rails 3 ruby​​ 1.9.2 CSV "already initialized constant .."警告