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
}
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
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_
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
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);
}
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 )
$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.
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);
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();
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
)
);
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);
}
}
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', ....]
);
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.