Existe alguma maneira de atualizar um registro no Laravel usando modelos eloquent apenas se uma alteração foi feita naquele registro? Não quero nenhum usuário solicitando o banco de dados sem um bom motivo repetidamente, apenas apertando o botão para salvar as alterações. Tenho uma javascript
função que habilita e desabilita o botão Salvar de acordo com se algo mudou na página, mas gostaria de saber se é possível ter certeza de fazer esse tipo de recurso no servidor também. Eu sei que posso fazer isso sozinho (ou seja: sem apelar para uma funcionalidade interna do framework) apenas verificando se o registro mudou, mas antes de fazer dessa forma, gostaria de saber se o modelo eloquent do Laravel já cuida isso, então não preciso reinventar a roda.
É assim que eu uso para atualizar um registro:
$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
sinalizador que é usado para determinar se uma atualização no banco de dados é realmente necessária, e este sinalizador é definido comparando osfind
valores da coluna original com os valores no ponto onde você executa o salvamentoRespostas:
Você já está fazendo isso!
save()
irá verificar se algo mudou no modelo. Se não tiver, não executará uma consulta de banco de dados.Esta é a parte relevante do código em
Illuminate\Database\Eloquent\Model@performUpdate
:protected function performUpdate(Builder $query, array $options = []) { $dirty = $this->getDirty(); if (count($dirty) > 0) { // runs update query } return true; }
O
getDirty()
método simplesmente compara os atributos atuais com uma cópia salvaoriginal
quando o modelo é criado. Isso é feito nosyncOriginal()
método:public function __construct(array $attributes = array()) { $this->bootIfNotBooted(); $this->syncOriginal(); $this->fill($attributes); } public function syncOriginal() { $this->original = $this->attributes; return $this; }
Se quiser verificar se o modelo está sujo é só ligar
isDirty()
:if($product->isDirty()){ // changes have been made }
Ou se você deseja verificar um determinado atributo:
if($product->isDirty('price')){ // price has changed }
fonte
isDirty()
para isso. Veja a resposta atualizadaisDirty()
.getChanges()
método. Verifique minha resposta stackoverflow.com/a/54132163/1090395isDirty()
serátrue
se você não definir seus atributos corretamente. Eu tinha um float que era exatamente igual ao do banco de dados, no entanto, como eu estava configurando o float com uma string (exemplo "10.50" em vez de 10.50), ele o detectaria como uma alteração e faria uma atualização.Você pode usar
getChanges()
no modelo Eloquent mesmo depois de persistir.fonte
Eu gosto de adicionar este método, se você estiver usando um formulário de edição, você pode usar este código para salvar as alterações em sua
update(Request $request, $id)
função:tenha em mente que você deve nomear suas entradas com o mesmo nome de coluna. A
fill()
função fará todo o trabalho para você :)fonte
fill
e como enviar a solicitação em massa para ele. Obrigado! Não precisei passar o ID, pois estou atualizando, então já está lá$request->id
.