wake-up-neo.com

Erstellen und Aktualisieren von Laravel Eloquent

Was ist die Abkürzung für das Einfügen eines neuen Datensatzes oder das Aktualisieren, falls er nicht existiert?

<?php

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

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

Hier ist ein vollständiges Beispiel dafür, worüber "lu cip" gesprochen hat:

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

Nachfolgend finden Sie den aktualisierten Link der Dokumente, der sich auf der neuesten Version von Laravel befindet

Dokumente hier: Link aktualisiert

198
weotch

Aktualisiert: 27. August 2014 - [updateOrCreate In den Kern eingebaut ...]

Nur für den Fall, dass die Leute immer noch darauf stoßen ... Ich habe ein paar Wochen nach dem Schreiben festgestellt, dass dies tatsächlich ein Teil des Kerns von Laravel Eloquent ist ...

Suche nach den gleichwertigen Methoden von Eloquent. Sie können hier sehen: 

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

on: 570 und: 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;
    }

Alte Antwort unten


Ich frage mich, ob es eine L4-Funktionalität gibt, um dies auf eine Art zu tun, wie: 

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

Ich habe diese Methode vor ein paar Wochen erstellt ...

// 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;
}

Ich hoffe das hilft. Ich würde gerne eine Alternative dazu sehen, wenn jemand eine hat. @ erikthedev_

68
Erik Aybar

Wie in Laravel> = 5.3, wenn jemand noch neugierig ist, wie man das auf einfache Weise macht. Es ist möglich mit: updateOrCreate().

Zum Beispiel für die gestellte Frage können Sie Folgendes verwenden:

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

Mit dem obigen Code wird die von ShopMeta dargestellte Tabelle überprüft. Dies ist höchstwahrscheinlich shop_metas, sofern nicht im Modell selbst etwas anderes definiert ist 

und es wird versucht, einen Eintrag mit zu finden 

spalte shopId = $theID 

und 

spalte metadateKey = 2001 

wenn es gefunden wird, wird die Spalte shopOwner der gefundenen Zeile auf New One aktualisiert.

Wenn mehr als eine übereinstimmende Zeile gefunden wird, wird die erste Zeile aktualisiert, dh die niedrigste primäre id.

Wenn überhaupt nicht gefunden, wird eine neue Zeile eingefügt mit:

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

Notice Überprüfen Sie Ihr Modell auf $fillable und stellen Sie sicher, dass Sie dort jeden Spaltennamen definiert haben, den Sie einfügen oder aktualisieren möchten. Restspalten haben entweder einen Standardwert oder die id-Spalte wird automatisch um eins erhöht.

Andernfalls wird beim Ausführen des obigen Beispiels ein Fehler ausgegeben:

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))'

Da es ein Feld gibt, das beim Einfügen einer neuen Zeile einen Wert benötigt, ist es nicht möglich, da es entweder nicht in $fillable definiert ist oder keinen Standardwert hat.

Weitere Informationen finden Sie in der Laravel-Dokumentation unter: https://laravel.com/docs/5.3/eloquent

Ein Beispiel von dort ist:

// 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]
);

was ziemlich alles klar macht.

Ich hoffe, es hilft

44
Learner

Speicherfunktion:

$shopOwner->save()

mach schon was du willst ... 

Laravel-Code:

    // 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);
    }
16
lu cip

firstOrNew erstellt einen Datensatz, falls er nicht vorhanden ist, und aktualisiert eine Zeile, falls bereits vorhanden . Sie können auch updateOrCreate verwenden. Hier ist das vollständige Beispiel

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

Wenn es einen Flug von Oakland nach San Diego gibt, setzen Sie den Preis auf 99 $. wenn nicht vorhanden, neue Zeile erstellen

Referenzdokument hier: ( https://laravel.com/docs/5.5/eloquent )

10
Saeed Ansari
$shopOwner = ShopMeta::firstOrNew(array('shopId' => $theID,'metadataKey' => 2001));

Nehmen Sie dann Ihre Änderungen vor und speichern Sie. Beachten Sie, dass firstOrNew die Einfügung nicht ausführt, wenn sie nicht gefunden wird. Wenn Sie das dann benötigen, dann ist es firstOrCreate. 

5
malhal

Wenn Sie die gleiche Funktionalität mit der DB benötigen, können Sie in Laravel >= 5.5 Folgendes verwenden:

DB::table('table_name')->updateOrInsert($attributes, $values);

oder die Kurzversion, wenn $attributes und $values gleich sind:

DB::table('table_name')->updateOrInsert($values);
4
Sasa Blagojevic

Eine weitere Option, wenn Ihre ID nicht automatisch eingefügt wird und Sie wissen, welche ID eingefügt/aktualisiert werden soll:

$object = MyModel::findOrNew($id);
//assign attributes to update...
$object->save();
2
vivoconunxino

Eigentlich firstOrCreate würde nicht update für den Fall, dass das Register bereits in der DB vorhanden ist . Ich habe Eriks Lösung etwas verbessert, da ich eigentlich eine Tabelle mit eindeutigen Werten nicht nur für die Spalte aktualisieren musste "Ich würde"

/**
 * If the register exists in the table, it updates it. 
 * Otherwise it creates it
 * @param array $data Data to Insert/Update
 * @param array $keys Keys to check for in the table
 * @return Object
 */
static function createOrUpdate($data, $keys) {
    $record = self::where($keys)->first();
    if (is_null($record)) {
        return self::create($data);
    } else {
        return self::where($keys)->update($data);
    }
}

Dann würdest du es so benutzen:

Model::createOrUpdate(
        array(
    'id_a' => 1,
    'foo' => 'bar'
        ), array(
    'id_a' => 1
        )
);
1
Juancho Ramone

wie @JuanchoRamone oben (danke @Juancho) ist es sehr nützlich für mich, aber wenn Ihre Daten Array sind, sollten Sie ein wenig wie folgt ändern:

public static function createOrUpdate($data, $keys) {
    $record = self::where($keys)->first();
    if (is_null($record)) {
        return self::create($data);
    } else {
        return $record->update($data);
    }
}
1
Duy Ngo

Wie die firstOrCreate-Methode bleibt updateOrCreate das Modell erhalten, es ist also nicht nötig, save () aufzurufen.

// 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]
);

Und für dein Problem

$shopOwner = ShopMeta::updateOrCreate(
   ['shopId' => $theID, 'metadataKey' => '2001'],
   ['other field' => 'val' ,'other field' => 'val', ....]
);
1

Stimmt das nicht mit updateOrCreate () überein?

Es ist ähnlich, aber nicht dasselbe. UpdateOrCreate () funktioniert nur für eine Zeile zu einer Zeit, die keine Masseneinfügung zulässt . InsertOnDuplicateKey funktioniert in vielen Zeilen.

https://github.com/yadakhov/insert-on-duplicate-key

0