web-dev-qa-db-fra.com

Laravel Mise à jour éloquente uniquement si des modifications ont été apportées

Est-il possible de mettre à jour un enregistrement dans Laravel en utilisant des modèles éloquents uniquement si une modification a été apportée à cet enregistrement? Je ne souhaite pas qu'un utilisateur demande la base de données sans raison valable, encore et encore , en appuyant simplement sur le bouton pour enregistrer les modifications. J'ai une fonction javascript qui active et désactive le bouton d’enregistrement en fonction de la modification éventuelle de la page, mais je voudrais savoir s’il est possible de s’assurer de le faire. Je sais que je peux le faire moi-même (c'est-à-dire sans faire appel à une fonctionnalité interne du framework) simplement en vérifiant si l'enregistrement a changé, mais avant de le faire de cette façon, j'aimerais savoir si Laravel s'en occupe déjà, alors je n'ai pas besoin de réinventer la roue.

Voici comment j'utilise pour mettre à jour un enregistrement:

$product = Product::find($data["id"]);
$product->title = $data["title"];
$product->description = $data["description"];
$product->price = $data["price"];
//etc (string values were previously sanitized for xss attacks)
$product->save();
68
user2755140

Tu le fais déjà!

save() vérifiera si quelque chose a changé dans le modèle. Sinon, aucune requête de base de données ne sera exécutée.

Voici la partie de code pertinente dans Illuminate\Database\Eloquent\Model@performUpdate:

protected function performUpdate(Builder $query, array $options = [])
{
    $dirty = $this->getDirty();

    if (count($dirty) > 0)
    {
        // runs update query
    }

    return true;
}

La méthode getDirty() compare simplement les attributs actuels à une copie enregistrée dans original lors de la création du modèle. Ceci est fait dans la méthode syncOriginal():

public function __construct(array $attributes = array())
{
    $this->bootIfNotBooted();

    $this->syncOriginal();

    $this->fill($attributes);
}

public function syncOriginal()
{
    $this->original = $this->attributes;

    return $this;
}

Si vous voulez vérifier si le modèle est sale, appelez simplement isDirty():

if($product->isDirty()){
    // changes have been made
}

Ou si vous voulez vérifier un certain attribut:

if($product->isDirty('price')){
    // price has changed
}
139
lukasgeiter

J'aime ajouter cette méthode, si vous utilisez un formulaire d'édition, vous pouvez utiliser ce code pour enregistrer les modifications dans votre fonction update(Request $request, $id):

$post = Post::find($id);    
$post->fill($request->input())->save();

n'oubliez pas que vous devez nommer vos entrées avec le même nom de colonne. La fonction fill() fera tout le travail pour vous :)

10
Ahmad Yousef

Vous pouvez utiliser getChanges() sur le modèle Eloquent même après avoir persisté.

4
Mladen Janjetovic