Laravel Eloquent update just if changes have been made

PhpLaravelEloquent

Php Problem Overview


Is there any way to update a record in Laravel using eloquent models just if a change has been made to that record? I don't want any user requesting the database for no good reason over and over, just hitting the button to save changes. I have a javascript function that enables and disables the save button according with whether something has changed in the page, but I would like to know if it's possible to make sure to do this kind of feature on the server side too. I know I can accomplish it by myself (meaning: without appealing to an internal functionality of the framework) just by checking if the record has change, but before doing it that way, I would like to know if Laravel eloquent model already takes care of that, so I don't need to re-invent the wheel.

This is the way I use to update a record:

$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();

Php Solutions


Solution 1 - Php

You're already doing it!

save() will check if something in the model has changed. If it hasn't it won't run a db query.

Here's the relevant part of code 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;
}

The getDirty() method simply compares the current attributes with a copy saved in original when the model is created. This is done in the syncOriginal() method:

public function __construct(array $attributes = array())
{
	$this->bootIfNotBooted();

	$this->syncOriginal();

	$this->fill($attributes);
}

public function syncOriginal()
{
	$this->original = $this->attributes;

	return $this;
}

If you want to check if the model is dirty just call isDirty():

if($product->isDirty()){
    // changes have been made
}

Or if you want to check a certain attribute:

if($product->isDirty('price')){
    // price has changed
}

Solution 2 - Php

You can use $product->getChanges() on Eloquent model even after persisting. Check docs here

Solution 3 - Php

I like to add this method, if you are using an edit form, you can use this code to save the changes in your update(Request $request, $id) function:

$post = Post::find($id);    
$post->fill($request->input())->save();

keep in mind that you have to name your inputs with the same column name. The fill() function will do all the work for you :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2755140View Question on Stackoverflow
Solution 1 - PhplukasgeiterView Answer on Stackoverflow
Solution 2 - PhpMladen JanjetovicView Answer on Stackoverflow
Solution 3 - PhpAhmad YousefView Answer on Stackoverflow