0

假设我在管理我的 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. 管理员Sally想要更改描述。
  2. 管理员Sally使用此表单打开页面并开始在文本区域中编写一些新的销售副本。
  3. 几秒钟后,管理员Joe决定该产品需要上市销售
  4. 管理员打开带有表单的页面
  5. 管理员将价格降至 9.99 美元
  6. 管理员乔提交表单,将数据库中的价格设置为 9.99 美元
  7. 管理员Sally完成了副本的编写并提交了表单,但她浏览器中的价格字段仍然显示为 12.99 美元。
  8. 很生气,对莎莉大喊大叫,因为她把价格改回来了,尽管她不知道自己只是这么做了。

因此,数据库更新为包含Sally在表单中的内容,删除了Joe在打开该页面时设置的价格。

当然,我不是第一个偶然发现此类问题的人,但我从来没有处理过它。那么首先,这类问题有名称吗?其次,有什么解决方案可以减少它的吸吮?


我想到了一些解决方案,但有些有严重的缺点。

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

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

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

但同样,我确信我不是第一个遇到这个问题的人。那么有没有标准的解决方案呢?

4

1 回答 1

2

Have you checked this: http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html ?

UPDATE

Well, it doesn't really explain what to do if lock_version is wrong, but at least it's better than updated_at I guess. It all depends on who wins and why. If Sally didn't touch price it seems reasonable to update price from Joe's data when saving. Just add original values as hidden fields and compare them with Sally's input when saving in case lock_version is wrong. If they both modified same field, well, no luck. Somebody should win, or you can go back to the edit page and highlight changes for acceptance.

于 2012-09-13T19:08:24.633 回答