191 votes

Création et mise à jour de Laravel Eloquent

Quelle est l'abréviation pour insérer un nouvel enregistrement ou mettre à jour un enregistrement existant ?

<?php

$shopOwner = ShopMeta::where('shopId', '=', $theID)
    ->where('metadataKey', '=', 2001)->first();

if ($shopOwner == null) {
    // Insert new record into database
} else {
    // Update the existing record
}

251voto

weotch Points 1118

Voici un exemple complet de ce dont "lu cip" parlait :

$user = User::firstOrNew(array('name' => Input::get('name')));
$user->foo = Input::get('foo');
$user->save();

Vous trouverez ci-dessous le lien de la documentation mise à jour pour la dernière version de Laravel.

Docs ici : Lien actualisé

114voto

Learner Points 3627

Mise à jour 2020

Comme dans Laravel >= 5.3 Si quelqu'un est toujours curieux de savoir comment le faire facilement, il peut le faire en utilisant le système de gestion de l'information : updateOrCreate() .

Par exemple pour la question posée vous pouvez utiliser quelque chose comme :

$matchThese = ['shopId'=>$theID,'metadataKey'=>2001];
ShopMeta::updateOrCreate($matchThese,['shopOwner'=>'New One']);

Le code ci-dessus vérifiera la table représentée par ShopMeta, qui sera très probablement shop_metas sauf s'il n'est pas défini autrement dans le modèle lui-même.

Et il essaiera de trouver une entrée avec

colonne shopId = $theID

et

colonne metadateKey = 2001

et s'il le trouve, il mettra à jour la colonne shopOwner de la ligne trouvée à New One .

S'il trouve plus d'une ligne correspondante, il mettra à jour la toute première ligne, c'est-à-dire celle qui a la plus petite valeur primaire. id .

Si elle n'est pas trouvée, une nouvelle ligne sera insérée avec le code :

shopId = $theID , metadateKey = 2001 y shopOwner = New One

Avis Vérifiez votre modèle pour $fillable et assurez-vous que vous avez défini chaque nom de colonne que vous voulez insérer ou mettre à jour et que les autres colonnes ont soit une valeur par défaut, soit sa valeur de base. id colonne auto incrémentée de un.

Sinon, il y aura une erreur lors de l'exécution de l'exemple ci-dessus :

Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1364 Field '...' doesn't have a default value (SQL: insert into `...` (`...`,.., `updated_at`, `created_at`) values (...,.., xxxx-xx-xx xx:xx:xx, xxxx-xx-xx xx:xx:xx))'

Comme il y aurait un champ qui aurait besoin d'une valeur lors de l'insertion d'une nouvelle ligne et que cela ne serait pas possible, soit parce qu'il n'est pas défini dans la base de données de l'utilisateur. $fillable ou il n'a pas de valeur par défaut.

Pour plus de références, veuillez consulter la documentation de Laravel à l'adresse suivante : https://laravel.com/docs/5.3/eloquent

En voici un exemple :

// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99]
);

ce qui efface à peu près tout.

Mise à jour de Query Builder

Quelqu'un a demandé s'il était possible d'utiliser Query Builder dans Laravel. Ici est la référence pour Query Builder dans la documentation de Laravel.

Query Builder fonctionne exactement de la même manière qu'Eloquent, donc tout ce qui est vrai pour Eloquent l'est également pour Query Builder. Donc pour ce cas spécifique, utilisez la même fonction avec votre query builder comme ceci :

$matchThese = array('shopId'=>$theID,'metadataKey'=>2001);
DB::table('shop_metas')::updateOrCreate($matchThese,['shopOwner'=>'New One']);

Bien sûr, n'oubliez pas d'ajouter la façade DB :

use Illuminate\Support\Facades\DB;

OU

use DB;

91voto

ErikTheDeveloper Points 267

Mise à jour : Aug 27 2014 - [ updateOrCreate Intégrée dans le noyau...]

Juste au cas où des gens tomberaient encore sur ce sujet... J'ai découvert quelques semaines après avoir écrit ceci, que cela fait en fait partie du noyau d'Eloquent de Laravel...

Creuser dans la ou les méthodes équivalentes d'Eloquent. Vous pouvez voir ici :

https://github.com/laravel/framework/blob/4.2/src/Illuminate/Database/Eloquent/Model.php#L553

sur :570 et :553

    /**
     * Create or update a record matching the attributes, and fill it with values.
     *
     * @param  array  $attributes
     * @param  array  $values
     * @return static
     */
    public static function updateOrCreate(array $attributes, array $values = array())
    {
        $instance = static::firstOrNew($attributes);

        $instance->fill($values)->save();

        return $instance;
    }

Ancienne réponse ci-dessous


Je me demande s'il existe une fonctionnalité intégrée à L4 pour faire cela, par exemple :

$row = DB::table('table')->where('id', '=', $id)->first();
// Fancy field => data assignments here
$row->save();

J'ai créé cette méthode il y a quelques semaines...

// Within a Model extends Eloquent
public static function createOrUpdate($formatted_array) {
    $row = Model::find($formatted_array['id']);
    if ($row === null) {
        Model::create($formatted_array);
        Session::flash('footer_message', "CREATED");
    } else {
        $row->update($formatted_array);
        Session::flash('footer_message', "EXISITING");
    }
    $affected_row = Model::find($formatted_array['id']);
    return $affected_row;
}

J'espère que cela vous aidera. J'aimerais beaucoup voir une alternative à cela si quelqu'un en a une à partager. @erikthedev_

21voto

Saeed Ansari Points 407

firstOrNew va créer un enregistrement s'il n'existe pas et mettre à jour une ligne si elle existe déjà. Vous pouvez également utiliser updateOrCreate Voici l'exemple complet

$flight = App\Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99]
); 

S'il y a un vol de Oakland à San Diego, mettez le prix à 99 $. S'il n'y en a pas, créez une nouvelle ligne.

Document de référence ici : ( https://laravel.com/docs/5.5/eloquent )

18voto

lu cip Points 715

Fonction de sauvegarde :

$shopOwner->save()

faites déjà ce que vous voulez...

Code Laravel :

    // If the model already exists in the database we can just update our record
    // that is already in this database using the current IDs in this "where"
    // clause to only update this model. Otherwise, we'll just insert them.
    if ($this->exists)
    {
        $saved = $this->performUpdate($query);
    }

    // If the model is brand new, we'll insert it into our database and set the
    // ID attribute on the model to the value of the newly inserted row's ID
    // which is typically an auto-increment value managed by the database.
    else
    {
        $saved = $this->performInsert($query);
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X