防止多个用户之间的表单提交冲突(Rails 2.x)

时间:2012-09-13 19:04:23

标签: ruby-on-rails ruby

假设我在管理Rails 2.x网站时有一个简单的表单。

<form action="/products/123">

  Price:
  <input type="text" name="product[price]" value="12.99"></input>

  Description:
  <textarea name="product[description]">
    A long and descriptive block of text goes here.
  </textarea>

  <input type="submit"></input>
</form>
  1. 管理员莎莉想要更改说明。
  2. 管理员莎莉打开包含此表单的页面,并开始在textarea中写一些新的销售副本。
  3. 几秒钟后,管理员 Joe 决定此产品需要继续销售
  4. 管理员 Joe 打开包含表单的页面
  5. 管理员 Joe 将价格降至$ 9.99
  6. 管理员 Joe 提交表单,将数据库中的价格设置为9.99美元
  7. 管理员莎莉已完成撰写副本并提交表单,但她浏览器中的价格字段仍为12.99美元。
  8. 因为改变价格而对莎莉大吼大叫,尽管她不知道她只是这样做了。
  9. 因此,数据库已更新为包含 Sally 在表单中的内容,从而消除了 Joe 在打开该页面时设置的价格。

    当然,我不是第一个偶然发现这样一个问题的人,但我从来没有处理过这个问题。首先,这类问题有名吗?第二,有哪些解决方案可以减少吸收?


    我想到了一些解决方案,但有些解决方案存在严重缺陷。

    • 如果从打开表单时更改了updated_at时间戳,请不要保存记录。但是你要保存的内容会发生什么?您必须将要更改的内容复制到表单之外,重新加载编辑表单,然后将其粘贴回来,希望在此期间没有其他人编辑任何内容。

    • 表单加载大多数字段已禁用,要求管理员“解锁”他们要编辑的字段,并且只有解锁的字段会在提交时发送到服务器。这大大降低了大型表格冲突的可能性,但在内容编辑过程中添加了大量点击,即使在99%的情况下都会很好。

    • 基于JS的解决方案,可以进行脏字段检查,禁用任何与加载表单时具有相同值的表单输入,因此只提交了更改的字段,我想这个选项到目前为止最好,我猜。但它确实听起来有点复杂,并涉及将我的模型转储到页面上的JSON,以便与表单提交处理程序进行比较。

    但是,我相信我不是第一个遇到这个问题的人。那么有一个标准的解决方案吗?

1 个答案:

答案 0 :(得分:2)

你检查过这个:http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html

<强>更新

嗯,如果lock_version错误,它并没有真正解释该做什么,但至少它比{}}}更好。这一切都取决于谁赢了,为什么。如果莎莉没有触及价格,保存时从 Joe 的数据更新价格似乎是合理的。只需将原始值添加为隐藏字段,并在保存updated_at错误时将其与 Sally 的输入进行比较。如果他们都修改了相同的字段,那么,没有运气。有人应该获胜,或者您可以返回编辑页面并突出显示更改以供接受。