Gibt es eine Möglichkeit, einen Datensatz in Laravel mithilfe beredter Modelle zu aktualisieren, wenn eine Änderung an diesem Datensatz vorgenommen wurde? Ich möchte nicht, dass ein Benutzer die Datenbank ohne guten Grund immer wieder anfordert und nur auf die Schaltfläche drückt, um Änderungen zu speichern. Ich habe eine javascript
Funktion, die die Schaltfläche zum Speichern aktiviert und deaktiviert, je nachdem, ob sich etwas auf der Seite geändert hat, aber ich möchte wissen, ob es möglich ist, diese Art von Funktion auch auf der Serverseite auszuführen. Ich weiß, dass ich es selbst schaffen kann (dh ohne auf eine interne Funktionalität des Frameworks einzugehen), indem ich nur überprüfe, ob sich der Datensatz geändert hat, aber bevor ich es auf diese Weise mache, möchte ich wissen, ob sich das beredte Laravel-Modell bereits darum kümmert das, also muss ich das Rad nicht neu erfinden.
So aktualisiere ich einen Datensatz:
$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();
dirty
Flag enthalten, mit dem bestimmt wird, ob tatsächlich eine Aktualisierung der Datenbank erforderlich ist. Dieses Flag wird gesetzt, indem die ursprünglichenfind
Spaltenwerte mit den Werten an dem Punkt verglichen werden, an dem Sie das Speichern ausführenAntworten:
Du machst es schon!
save()
prüft, ob sich etwas im Modell geändert hat. Wenn dies nicht der Fall ist, wird keine Datenbankabfrage ausgeführt.Hier ist der relevante Teil des Codes in
Illuminate\Database\Eloquent\Model@performUpdate
:protected function performUpdate(Builder $query, array $options = []) { $dirty = $this->getDirty(); if (count($dirty) > 0) { // runs update query } return true; }
Die
getDirty()
Methode vergleicht einfach die aktuellen Attribute mit einer Kopie, die beimoriginal
Erstellen des Modells gespeichert wurde . Dies geschieht in dersyncOriginal()
Methode:public function __construct(array $attributes = array()) { $this->bootIfNotBooted(); $this->syncOriginal(); $this->fill($attributes); } public function syncOriginal() { $this->original = $this->attributes; return $this; }
Wenn Sie überprüfen möchten, ob das Modell verschmutzt ist, rufen Sie einfach an
isDirty()
:if($product->isDirty()){ // changes have been made }
Oder wenn Sie ein bestimmtes Attribut überprüfen möchten:
if($product->isDirty('price')){ // price has changed }
quelle
isDirty()
. Siehe die aktualisierte AntwortisDirty()
.getChanges()
Methode. Überprüfen Sie meine Antwort stackoverflow.com/a/54132163/1090395isDirty()
wird es sein,true
wenn Sie Ihre Attribute nicht richtig umsetzen . Ich hatte einen Float, der genau der gleiche war wie in der Datenbank. Da ich den Float jedoch mit einer Zeichenfolge (Beispiel "10.50" anstelle von 10.50) festlegte, wurde er als Änderung erkannt und eine Aktualisierung durchgeführt.Sie können das
getChanges()
Eloquent-Modell auch nach dem Fortbestehen verwenden.quelle
Ich möchte diese Methode hinzufügen. Wenn Sie ein Bearbeitungsformular verwenden, können Sie diesen Code verwenden, um die Änderungen in Ihrer
update(Request $request, $id)
Funktion zu speichern :Beachten Sie, dass Sie Ihre Eingaben mit demselben Spaltennamen benennen müssen. Die
fill()
Funktion erledigt die ganze Arbeit für Sie :)quelle
fill
und erfahren, wie ich eine Massenanforderung an ihn weiterleiten kann. Vielen Dank! Ich musste die ID allerdings nicht weitergeben, da ich sie aktualisiere, also ist sie bereits da$request->id
.