Rails2.xを利用したWebサイトの管理に簡単なフォームがあるとしましょう。
<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>
- 管理者サリーは説明を変更したいと考えています。
- 管理者サリーはこのフォームでページを開き、テキストエリアに新しいセールスコピーを書き始めます。
- 数秒後、管理者のジョーはこの製品を販売する必要があると判断しました
- 管理者ジョーは、フォームが記載されたページを開きます
- 管理者ジョーは価格を9.99ドルに下げます
- 管理者Joeがフォームを送信し、データベースの価格を$9.99に設定します
- 管理者サリーはコピーの作成とフォームの送信を完了しましたが、ブラウザの価格フィールドにはまだ$12.99と表示されています。
- ジョーは怒ってサリーに怒鳴り、価格を元に戻したのですが、彼女はそれをやったとは思っていませんでした。
そのため、データベースはサリーがフォームに持っていたものを含むように更新され、ジョーがそのページを開いて作業しているときに設定した価格が削除されます。
確かに私はこのような問題に遭遇した最初の人ではありませんが、私はそれに対処する必要はありませんでした。それで、まず第一に、この種の問題には名前がありますか?そして第二に、それをより少なく吸うようにするためのいくつかの解決策は何ですか?
頭に浮かぶいくつかの解決策がありますが、いくつかには重大な欠点があります。
updated_at
フォームを開いたときからタイムスタンプが変更された場合は、レコードを保存しないでください。しかし、保存したいコンテンツはどうなりますか?変更したいコンテンツをフォームからコピーし、編集フォームをリロードしてから貼り付ける必要があります。その間、他の人が何も編集しないことを期待してください。ほとんどのフィールドが無効になっている状態でフォームが読み込まれるため、管理者は編集するフィールドを「ロック解除」する必要があり、ロック解除されたフィールドのみが送信時にサーバーに送信されます。これにより、大きなフォームでの競合の可能性が大幅に減少しますが、99%の確率で問題がない場合でも、コンテンツ編集プロセスに大量のクリックが追加されます。
ダーティフィールドチェックを実行し、フォームがロードされたときと同じ値を持つフォーム入力を無効にするJSベースのソリューション。変更されたフィールドのみが送信されるため、これまでのところ、このオプションが最も気に入っていると思います。しかし、それは少し複雑に聞こえます。フォーム送信ハンドラーと比較するために、ページ上のJSONにモデルをダンプする必要があります。
しかし、繰り返しになりますが、私はこの問題を抱えている最初の人ではないと確信しています。それで、これに対する標準的な解決策はありますか?