Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - User Pressing 'Back' after object creation, Creating Duplicates

I'm having a problem where when a user fills out my evaluation form, click "Create", then click the browser's back button, make some edits, and click "Create" again, it's creating duplicate Evaluations.

What is the best way to prevent something like this happening.

Only ONE evaluation should exist for each survey_criterion on creation. I don't want the user to lose any data they enter after hitting the back button, filling out the form with new stuff, and clicking "Create" again.

UPDATE

routes.rb

resources :survey_criteria do
  resources :groups do
    resources :evaluations
  end
end

survey_criterion.rb

has_many :evaluations

evaluation.rb

belongs_to :survey_criterion
belongs_to :group

There are more complicated associations, but the answer I'm looking for is more, "how does one handle it when users press the 'Back' button, modify the form, then click Create again".

I want it to update the one that was automatically created I think in this instance, and not throw an error to the user. I know I could add a validation that would error out, but I want this to be invisible to the user I think.

Thoughts?

like image 808
ardavis Avatar asked Dec 05 '11 22:12

ardavis


3 Answers

The simplest solution, would be to change the create action, which should work like this pseudocode:

def create
  # ...
  if evaluation_exists?
    update_evaluation(params[:evaluation])
  else
    create_evaluation(params[:evaluation])
  end
  # ...
end

As for Your question "how does one handle it when users press the 'Back' button, modify the form, then click Create again", then I use some random token (a short string) placed as a hidden field in the form.

When the create-request comes, I check whether this token is already stored in the session. If it is not, then I create the object, and add that token to the list of used ones. If the token is already present in the session, I know that user has just resubmitted the form, and I can act accordingly. Usually I ask him whether another object should be created. In the session I store usually not more that 3-5 tokens.

It looks like this (yes, that's just an illustration):

def create
  token = params[:token]
  session[:tokens] ||= []
  if session[:tokens].include? token
    render_the_form_again( "You have already created the object. Want another?" )
  else
    create_the_object
    session[:tokens] << token
  end
  # ...
end
like image 57
Arsen7 Avatar answered Oct 17 '22 22:10

Arsen7


In your Evaluation model, add this line :

validates_uniqueness_of :survey_criterion_id

This is assuming that SurveyCriterion holds the foreign key that associates with your Evaluation.

like image 42
Trip Avatar answered Oct 18 '22 00:10

Trip


You can also do 2 things :

  1. Prevent the browser cache.
  2. Disable the Create button with :disable_with => "Processing" option.

It is discussed here too: https://stackoverflow.com/a/12112007/553371

like image 41
Jérémie Avatar answered Oct 17 '22 22:10

Jérémie