J'utilise Laravel 5.6.29
CharmFlag::updateOrCreate( ['post_id' => $postId, 'charm_id' => $charm_id], [ 'gif_flag' => $gif_flag, ] );
mais dans la base de données je peux voir des enregistrements comme
Maintenant, on peut voir qu'il y a des enregistrements en double pour charm_id = 18604
et charm_id = 18605
, mais selon ce que j'ai codé, cela ne devrait pas arriver.
Mettre à jour
Également changé le code en
Schema::create('charm_flags', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('post_id'); $table->unsignedInteger('charm_id'); $table->boolean('gif_flag')->default(0); $table->timestamps(); $table->foreign('post_id')->references('post_id')->on('posts'); $table->foreign('charm_id')->references('charm_id')->on('base_charms'); });
5 Réponses :
Vous n'avez pas besoin de vérifier isEmpty
, vous pouvez utiliser les méthodes firstOrNew ()
ou updateOrCreate ()
$charmFlag = CharmFlag::updateOrCreate(['post_id' => $postId, 'charm_id' => $charm_id]); $charmFlag->gif_flag = $gif_flag; $charmFlag->save();
Merci pour cela, mais y a-t-il un problème avec mon code?
Cela ne résout pas non plus mon problème, obtenant toujours des enregistrements en double.
J'espère que si vous mettez à jour votre table en utilisant une migration comme celle-ci $ table-> unique (['post_id', 'charm_id']);
cela résoudra votre problème
cela peut supprimer le mauvais enregistrement à l'étape actuelle, c'est pourquoi je ne change pas la migration.
L'ajout d'une contrainte unique ne modifiera pas les enregistrements existants. L'ajout de la contrainte échouera s'il existe des enregistrements qui ne correspondent pas à cette contrainte. Vous devriez vraiment avoir au moins un identifiant unique par ligne, peut-être la combinaison de postID et charmID.
@Qirel oui la combinaison de postID et charmID est unique, mais il y a d'autres colonnes à côté de gif_flag
et ces deux, ce que je peux faire est de garder la première entrée de chaque entrée en double et de supprimer la dernière, mais tout aussi important est d'éviter de nouvelles entrées en double.
@Sethu firstOrNew n'insérera que s'il n'existe pas, mais updateOrCreate se mettra à jour s'il existe et s'il n'existe pas, il s'insérera, donc plus tard, mon exigence est de ne pas obtenir de doublon.
@PrafullaKumarSahu J'ai déjà suggéré updateOrCreate
et je suis content que vous ayez la solution :)
@Sethu oui je sais, mais j'ai juste pensé à vous le faire savoir, j'ai également voté pour votre réponse car je l'ai trouvé utile, en m'attendant simplement à ne pas être dupliqué avec updateOrCreated, déjà supprimé les données en double déjà existantes et en attendant que de nouvelles données soient insérées pour vérifier si cela fonctionne bien car l'application est en ligne.
@Sethu mais toujours en double, vient d'obtenir 20/25 nouveaux enregistrements avec 4 doublons.
S'il existe un post_id et un charm_id , définissez le gif_flag . Si aucun modèle correspondant n'existe, créez-en un.
Vous pouvez essayer comme ceci:
CharmFlag::updateOrCreate( ['post_id' => $postId, 'charm_id' => $charm_id], ['gif_flag' => $gif_flag] );
Cela améliore également les performances de votre code.
Il fait la même chose que mon code, donc cela ne résout pas mon problème, mais j'aimerais vraiment savoir comment cela améliorera mes performances?
Au lieu d'exécuter plusieurs requêtes, vous en exécutez une et utilisez une variable à la place. Bien que la solution consistant à remplacer votre code actuel par celui de la réponse de Sethu soit probablement la façon la plus propre et la meilleure de s'y prendre.
vous pouvez essayer ceci, c'est le meilleur moyen de mettre à jour ou de créer s'il n'existe pas.
@Qirel J'ai mis à jour mon code, mais j'ai toujours des entrées en double!
@PrafullaKumarSahu: Avez-vous effacé votre base de données après avoir modifié le code?
@svikramjeet non, je ne peux pas effacer ma base de données, je recherche de nouvelles entrées et je trouve de nouvelles entrées en double.
CharmFlag :: updateOrCreate (['post_id' => $ postId, 'charm_id' => $ charm_id], ['gif_flag' => $ gif_flag]);
Cela ne devrait pas autoriser les entrées en double car clairement cette méthode sera mise à jour (si l'enregistrement existe) sinon créer un nouveau
@prafullaKumarSahu, je suis incapable de comprendre pourquoi le code n'a pas affecté la réponse
@SurenderSinghRawat c'est déroutant pour moi aussi, les gens travaillent sur cette application et je garde les yeux sur les nouvelles entrées et il semble que rien ne résout le problème.
@SurenderSinghRawat oui j'ai juste essayé cette commande ainsi que php artisan cache: clear
mais ne semble pas changer le résultat.
@PrafullaKumarSahu, en fait c'est un tableau croisé dynamique pour cette vérification ma réponse stackoverflow.com/questions/55718378/...
@SurenderSinghRawat non ce n'est pas un tableau croisé dynamique, c'est un nouveau modèle, j'ai donné des exemples de données en sélectionnant des colonnes car c'était trop long.
veuillez également mettre à jour la classe et la migration dans votre question.
Laissez-nous continuer cette discussion dans le chat .
Il y a une préférence pour firstOrNew
, mais après avoir parcouru la documentation, je dois dire que updateOrCreate
est plus préférable dans mon cas.
Les chances de créer des doublons se trouvent dans la première condition, -> get () -> isEmpty ()
cela ne semble pas fonctionner.
Pouvez-vous mettre à jour votre requête comme ceci et voir. p>
if (CharmFlag::where('post_id', '=', $postId)->where('charm_id', '=', $charm_id)->first()) { CharmFlag::create([ 'post_id' => $postId, 'charm_id' => $charm_id, 'gif_flag' => $gif_flag ]); } else { $charmFlag = CharmFlag::where('post_id', '=', $postId)->where('charm_id', '=', $charm_id)->first(); $charmFlag->gif_flag = $gif_flag; $charmFlag->save(); // you can also use below for update. this is faster and efficient. /* CharmFlag::updateOrCreate( ['post_id' => $postId, 'charm_id' => $charm_id], ['gif_flag' => $gif_flag] ); */ }
essayez ceci:
$charmFlag = CharmFlag::where([['post_id',$postId],['charm_id',$charmId]])->first(); if($charmFlag) $charmFlag->gifFlag = $gif_flag; else { $charmFlag = new CharmFlag(); $charmFlag->post_id = $postId; $charmFlag->charm_id = $charm_id; $charmFlag->gif_flag = $gif_flag; } $charmFlag->save();
Aucune des réponses publiées n'a fonctionné pour moi, donc basée sur des suggestions de commentaires
DELETE FROM charm_flags WHERE id IN (SELECT * FROM (SELECT MAX (n.id) FROM charm_flags n GROUP BY post_id, charm_id HAVING COUNT (*)> 1) x)
Schema :: table ('charm_flags', function (Blueprint $ table) {
$ table-> unique (["post_id", "charm_id"]);
});
s'il existe une meilleure solution, j'aimerais l'apprendre.
vous obtenez juste -> premier () pas tous multiples
@DanyalSandeelo J'obtiens peu d'enregistrements corrects et peu de doublons, si vous pouvez remarquer la combinaison
3260-18604
et3260-18605
.@Tarasovych orWhere ne fonctionnera jamais, j'ai besoin d'une combinaison de
post_id
etcharm_id
pour être unique et en bricolant la condition fonctionne bien.Voulez-vous éviter d'enregistrer des enregistrements en double dans la base de données?, Car comme je le vois, la valeur
created_at
pour les entrées en double est la mêmeCharmFlag :: where ('post_id', '=', $ postId) -> where ('charm_id', '=', $ charm_id) -> first ();
cela ne renverrait qu'un seul enregistrement@RahulMeshram oui, je veux éviter les entrées en double dans la base de données pour lesquelles la combinaison post_id et charm_id est la même.
Ensuite, créez une migration pour modifier cette table avec une combinaison unique, ce sera mieux pour vous.
$ table-> unique (array ('charm_id', 'post_id'));
comme ceci.Ainsi, vous pouvez
CharmFlag :: where ('post_id', '=', $ postId) -> where ('charm_id', '=', $ charm_id) -> count ()
, si valeur est supérieur à 0, vous accédez au caselse
Je conseille d'utiliser
FormRequest
dans ce cas, afin d'éviter de futures duplications. Vous pouvez utiliser la règleunique
pour la validation.@RahulMeshram Je n'essaye pas de récupérer l'enregistrement unique, je veux éviter une entrée en double dans la table, comme mon code semble correct, j'aimerais savoir comment cette exception peut se produire.
Exactement, mon pote, l'extrait que j'ai partagé avec vous évitera toute autre entrée à enregistrer dans la base de données.
@Tarasovych
isEmpty ()
faisant la même chose quecount () == 0
.@RahulMeshram au lieu d'utiliser un tableau, puis-je utiliser le modèle?
link c'est la manière la plus sûre de le faire. Et au niveau du modèle, il vous suffit de détecter cette exception. Votre compagnon d'appel, je peux vous recommander le meilleur moyen.
@RahulMeshram qui semble bien, mais ne peut pas changer la migration maintenant, car cette soeur vit maintenant avec des millions de données.
@RahulMeshram enfin j'ai fait ce que vous aviez suggéré, changé la structure de table en utilisant une migration de modification, merci, cela signifie que toutes ces fonctions n'ont aucune garantie, la structure de la base de données doit être exactement ce dont nous avons besoin.