J'ai le code suivant dans mon contrôleur:
for($i=0; $i<$number_of_tourists; $i++) {
$tourist = Tourist::updateOrCreate(['doc_number' => $request['doc_number'][$i]],
$tourist_to_update);
}
chaque fois que "updateOrCreate" fonctionne, il fait 1 chose sur 3:
1) met à jour le modèle instantané OU
2) crée et enregistre un nouveau OU
3) laisse tout inchangé (si un modèle avec de telles valeurs existe déjà).
J'ai besoin de vérifier si 'updateOrCreate' a fait exactement 1 (mis à jour) puis exécuter du code.
Comment puis-je le faire?
Merci d'avance!
Dans Laravel 5.5 vous pouvez enfin vérifier si des mises à jour ont bien eu lieu avec la méthode wasChanged
$tourist = Tourist::updateOrCreate([...]);
// If true then created otherwise maybe updated
$wasRecentlyCreated = $tourist->wasRecentlyCreated;
// If true then tourist has been modified,
// otherwise either created or not updated
//
// Note: Before 5.7 it returned only true
// if database entry was modified.
$wasChanged = $tourist->wasChanged();
if(!$wasRecentlyCreated && $wasChanged){
// user existed and there were actually updates taking place.
}
if($wasRecentlyCreated && !$wasChanged){
// user has just been created. The row wasn't updated after creation.
}
// If true then the object `$tourist` has been modified but not saved
$tourist->isDirty();
//You can also check if a specific attribute was changed:
$tourist->wasChanged('name');
$tourist->isDirty('name');
Il est assez facile de déterminer si la fonction a entraîné une mise à jour ou une insertion (vérifiez la propriété wasRecentlyCreated
). Cependant, lorsque vous utilisez cette fonction, il est moins facile de déterminer si la mise à jour a réellement eu lieu (si le modèle existe mais n'est pas sale, aucune mise à jour ne sera effectuée). Je suggérerais de ne pas utiliser cette fonction et de diviser la fonctionnalité vous-même.
Voici la définition de la fonction:
public function updateOrCreate(array $attributes, array $values = [])
{
$instance = $this->firstOrNew($attributes);
$instance->fill($values)->save();
return $instance;
}
Pour intégrer cela dans votre code, je suggère quelque chose comme:
for ($i=0; $i<$number_of_tourists; $i++) {
$tourist = Tourist::firstOrNew(['doc_number' => $request['doc_number'][$i]]);
$tourist->fill($tourist_to_update);
// if the record exists and the fill changed data, update will be performed
$updated = $tourist->exists && $tourist->isDirty();
// save the tourist (insert or update)
$tourist->save();
if ($updated) {
// extra code
}
}
Si vous souhaitez toujours exécuter un code spécifique lors de la mise à jour d'une ligne, je vous recommande de créer un observer pour écouter les appels updated
ou create
.
<?php
namespace App\Observers;
use App\Tourist;
class TouristObserver
{
/**
* Listen to the User created event.
*
* @param \App\User $user
* @return void
*/
public function created(Tourist $user)
{
// this will always trigger when you created a new entry
}
/**
* Listen to the User deleting event.
*
* @param \App\Tourist $user
* @return void
*/
public function updated(Tourist $user)
{
// this will always trigger when actually a row was updated
}
}
Tout ce que vous avez à faire est d'enregistrer l'observateur dans AppServiceProvider
comme ceci:
public function boot()
{
Tourist::observe(\App\Observer\TouristObserver::class);
}
@patricus ci-dessous a présenté une méthode de travail pour résoudre le problème. si @TheFallen a donné ici une solution qui utilise Eloquent Events et semble plus élégante: Laravel Eloquent Events - implémente pour enregistrer le modèle si mis à jour
L'attribut de modèle "wasRecentlyCreated" ne serait "vrai" que s'il vient d'être créé.
Il existe une propriété nommée "changements" dans le modèle (il s'agit d'un tableau), qui détermine si le modèle a été mis à jour avec de nouvelles valeurs ou s'il a été enregistré tel quel sans apporter de modifications à son attribut.
Vérifiez l'extrait de code suivant:
// Case 1 : Model Created
if ($model->wasRecentlyCreated) {
} else { // Case 2 : Model Updated
if (count($model->changes)) { // model has been assigned new values to one of its attributes and saved successfully
} else { // model has NOT been assigned new values to one of its attributes and saved as is
}
}