0

Rails アプリで問題が発生しています。ユーザーがフォームで送信をクリックすると、ブラウザーの処理が停止し (KILL_CURSOR)、フォームを再送信すると、データベースに重複したエントリが作成されます。送信後の入力を無効にする JavaScript をインストールしようとしましたが、このユース ケースでは機能しません。

フォームが同じ認証トークンを持っていても、フォームが再送信されているかどうかを検証する方法はありますか?

これが私のコントローラーです:

def create
 @location = Location.new(params[:location])
 @location.user_id = current_user.id  

 if @location.save
  #refresh window to show new location
  render :js => "window.location.reload();"      
 #check that form fields have been completed properly
 else
  respond_to do |format|
  format.js
 end
end
4

1 に答える 1

1

まず、javascript を使用して送信ボタンを無効にすることをお勧めします。これはあなたのニーズを満たすだけでなく、ユーザーの行動に対する良いフィードバックを提供します。ただし、Web ブラウザーで JavaScript が無効になっている可能性があるため、これに頼ることはできません。

新しい文書を挿入する前に、データベースをチェックして、複製された文書が既に存在するかどうかを確認できます。ポイントは、重複の定義がビジネス ロジックに基づいているということです。たとえば、同じユーザーからの同じ場所に関する 5 分間の 2 つのリクエストが重複しています。ただし、極端な場合、2 つ以上の同時要求が重複したドキュメントになる可能性があります。これは、データベースを同時にチェックし、何も表示されずに挿入される可能性があるためです。

データベース層でunique indexは、データのいくつかのフィールド自体が重複を定義し、一意でなければならない場合、MongoDB で役立つ可能性があります。たとえば、特定の場所の特定のユーザーは、データベース内で最大 1 回出現する必要があります。一意のインデックスを構築する(user_id, location._id)ことで、その制約を保証できます。

db.collection.ensureIndex( { user_id: 1, location._id: 1 }, { unique: true } )

シャード キーでない限り、一意のインデックスはシャーディングでは許可されないことに注意してください。シャードキーでなければ、多くのマシンの中でそれを保証する簡単な方法がないからです。

于 2013-09-20T21:15:06.927 に答える