11
votes

Rails: Empêchez les inserts en double dues à appuyer sur le bouton arrière et sauvegardez à nouveau

Pensez à une application d'échafaudage simple de rails avec une "nouvelle" action contenant un formulaire pour ajouter des enregistrements à une base de données avec un bouton "Enregistrer". Après l'action "Créer", le contrôleur redirige vers l'action "Afficher", où l'utilisateur peut utiliser le lien "Modifier" pour modifier l'enregistrement juste inséré. Jusqu'à présent, si simple.

Mais si l'utilisateur utilise plutôt le bouton arrière du navigateur après avoir créé un enregistrement pour revenir à l'action "Nouvelle", le navigateur affiche le formulaire avec les valeurs que l'utilisateur est entré. Maintenant, il change certaines valeurs et appuie à nouveau "Enregistrer". Il pense que cela changerait le dossier, mais bien sûr cela crée un nouvel enregistrement.

Quel est le moyen préféré d'empêcher de telles entrées en double? Je cherche une solution générale, peut-être basée sur des cookies ou JavaScript.


2 commentaires

Quelles sont les données qui sont soumises? Y a-t-il un identifiant unique du tout que nous pouvons saisir?


Je pense à une solution générale, il devrait donc fonctionner pour tout type de données. Et ainsi, cela devrait également fonctionner s'il n'y a pas de valeur qui doit être unique.


8 Réponses :


0
votes

Vous pouvez utiliser des validateurs pour vous assurer qu'aucune valeur en double n'est insérée. Dans ce cas, validateate_uniqueness_of: champ code>

Si vous souhaitez par exemple empêcher les utilisateurs d'avoir la même adresse e-mail que vous pouvez mettre le code suivant dans votre modèle utilisateur. P>

validates_uniqueness_of :email


1 commentaires

Vous avez raison, mais cela ne fonctionne que s'il existe un champ qui doit être unique. Je cherche une solution plus générale.



3
votes

Vos validations de modèle garantiront des choses telles que les adresses électroniques sont uniques, mais je pense que cela est davantage sur la convivialité et l'expérience que toute autre chose.

Dites que vous parlez d'un formulaire de création de compte. Tout d'abord, votre formulaire Soumettre le bouton devrait dire quelque chose comme "Créer un compte" , au lieu de "Soumettre". Ensuite, selon que cela a été réussi ou non, affichez un message tel que l'un ou l'autre> créé avec succès " ou" il y avait des erreurs créant votre compte ". Si l'utilisateur voit ce message, ils sauront ce qui s'est passé.

Bien sûr, vous ne pouvez pas empêcher une personne de frapper le bouton arrière et de frapper à nouveau, mais vous devez concevoir pour la majorité des cas d'utilisation. S'ils arrivent à toucher, ils verront le bouton qui dit "Créer un compte". Vous devriez probablement avoir un autre texte sur la page qui dit "Veuillez vous inscrire à un nouveau compte pour commencer".

juste mon 0,02 $.


3 commentaires

Absolument: uxmovement.com/forms/...


Oui, une étiquette de bouton sophistiquée peut empêcher l'utilisateur de cliquer sur "Créer un compte" une seconde fois. Je suis d'accord avec vous que ce ne devrait pas être un simple "soumettre". Mais je ne le ferai pas. Il y a toujours des utilisateurs ignorant le texte du bouton et pensent pouvoir modifier l'enregistrement existant. Je cherche un moyen de reconnaître des choses et d'afficher un message comme "Vous essayez d'ajouter le même record deux fois!" Au lieu de cela, ou encore mieux, faire une mise à jour au lieu d'une création.


Et si l'utilisateur voulait réellement entrer dans le même record?



7
votes

Après quelques enquêtes, j'ai trouvé une solution appropriée basée sur des cookies. Ici, il est:

dans la "nouvelle" action du contrôleur, un horodatage avec l'heure actuelle est généré et rendu sous la forme de champ caché. Lorsque l'utilisateur soumet le formulaire, cet horodatage remonte à l'action "Créer" du contrôleur. Après avoir créé le disque, cet horodatage est stocké dans le cookie de session. Si l'utilisateur remonte au bouton "Nouveau" via le bouton arrière du navigateur, il obtient une forme fade, ce qui signifie que son horodatage est plus âgé que celui stocké dans le cookie. Ceci est vérifié avant de créer l'enregistrement et donne un message d'erreur.

Voici le code du contrôleur: xxx

et ici le code de formulaire: xxx


1 commentaires

Cette solution ne permettra pas de créer un nouveau message plus tard jusqu'à la session où Effacer, j'ai essayé de mettre en œuvre une solution rechargée qui, mais réussissez à travailler une fois (relâchement de: Last_Created_at après l'erreur et remplissez-la neuve avec || = heure. maintenant.to_i). Malheureusement, cette solution a une critique échoue si vous êtes revenu une fois de plus, la variable n'est jamais libérée et est la même erreur qui avant: /



2
votes

session ou cookie peut entraîner des effets côtés.

Je suis totalement d'accord: s'il existe un moyen de valider avec votre modèle, c'est le moyen le plus sûr d'empêcher les enregistrements en double. P>

Toujours que tu peux faire 2 choses. Empêcher la mise en cache du navigateur: les champs apparaissent vides dans le formulaire lorsque l'utilisateur clique sur le bouton arrière . Et désactiver le bouton "Créer" lorsque vous avez cliqué sur. P>

= f.submit "Create", :disable_with => "Processing..."


0 commentaires

6
votes

Quand j'ai eu le même problème, j'ai créé ce petit gemme qui la résout. Lorsque l'utilisateur frappe, il est redirigé vers le edit_path de l'enregistrement, au lieu de revenir au New_Path .

https://github.com/yossi-shasho/redirect_on_back < p> Vous pouvez faire quelque chose comme: xxx


4 commentaires

Ça a l'air bien, j'ai essayé de l'utiliser avec ActiveAdmin, mais je ne peux tout simplement pas être redirect_on_back_to travailler :( La prochaine fois que j'ai ce problème sans Aadmin, je vais lui donner un autre coup, merci!


@Alexis désolé d'entendre, pouvez-vous décrire le problème ou ouvrir un problème ici Github.com/yossi- shasho / redirect_on_wack / Problèmes s'il vous plaît?


Je ne sais pas si c'était une question, dans mon cas, j'ai essayé de remplacer l'action ActiveAdMin Créer une action et implémente la fonction, je suppose que c'est un peu délicat, ActiveAdMin utilise des ressources inhérentes et je ne connais pas complètement ceux-ci, Une autre idée vient à ce moment-là était peut-être que cela ne mettait peut-être pas la mise en œuvre des fonctions là-bas, mais ma connaissance ne me laisse pas essayer plus sur cette idée, à la manière, je l'utilise plus tard dans des contrôleurs normaux et fonctionne comme un charme, salutations!


génial, je suis heureux d'entendre :)



0
votes

base sur @georg Ledermann répondez, je fais cette petite snip de code pour rediriger le chemin de modification si l'utilisateur frappe puis hits Créer.

<%= hidden_field_tag :stale_form_check, @stale_form_check %>


0 commentaires

0
votes

Voici quelque chose qui a fonctionné pour moi.

Vous devrez faire 2 choses: créer une méthode dans votre contrôleur et ajouter une instruction conditionnelle dans le même contrôleur sous votre méthode "Créer".

1) Votre méthode doit renvoyer le nombre total de cet objet de cet utilisateur.

ex:

def utilisateur actuel_user.Object.count fin

2) Ajouter une instruction conditionnelle dans votre méthode "Créer".

Exemple:

def créer @Object = objet.create (objet_params) @ objet.save si User == 0 Redirect_to x_path fin

J'espère que cela vous aidera!


0 commentaires

0
votes

Ajouter html: {autocomplete: "Off"} code> dans votre form_for code> Comme ceci:

<%= form_for @object, url: xxx_path, html: { autocomplete: "off" } do |f| %>


0 commentaires