Rails - User by clicking "Back" after creating an object, Duplicate

I had a problem when a user fills out my assessment form, click "Create", then click the "Back" button of the browser, make some changes and click "Create" again, creating duplicate ratings.

What is the best way to prevent something like this.

Only one evaluation should exist for each survey_criterion at creation. I do not want the user to lose any data that they entered after clicking the "Back" button, filling out the form with new materials 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 complex associations, but the answer I'm looking for is more, "how to handle it when users click the" Back "button, change the form and then click" Create "again.

I want it to update the one that was automatically created. I think that in this instance, and did not give an error to the user. I know that I can add a check, which might be a mistake, but I want it to be invisible to the user I consider.

Thoughts?

+6
source share
4 answers

The simplest solution would be to modify 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 to handle it, when users click the "Back" button, change the form and then click "Create again" , then I use some random token (short line), placed as a hidden field in the form.

When a create request arrives, I check to see if this token is saved in the session. If this is not the case, I create an object and add this token to the list of used ones. If the token is already present in the session, I know that the user has just resubmitted the form, and I can act accordingly. I usually ask him if another object should be created. In a session, I usually store no more than 3-5 tokens.

It looks like this (yes, this is 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 
+6
source

In your assessment model, add the following line:

 validates_uniqueness_of :survey_criterion_id 

This assumes that SurveyCriterion contains a foreign key that is associated with your assessment.

+1
source

You can also do 2 things:

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

Also discussed here: fooobar.com/questions/650926 / ...

+1
source

A less elegant way, but a more general way to do this, is to use history.pushState . On the page after creation:

 $(function(){ if(history.pushState){ window.onpopstate = function(event){ if(window.history.state && window.history.state.previousStep){ window.location = window.history.state.previousStep; } } window.history.replaceState({ previousStep: '#{edit_resource_url(resource)}'}, document.title, window.location); window.history.pushState({}, document.title, window.location); } }) 

This example uses the HTML5 History API . A similar thing can be done with the backup project history.js

0
source

Source: https://habr.com/ru/post/903143/


All Articles