LaravelEloquent 更新,如果已经作出更改

如果 Laravel 的记录发生了变化,有没有办法用雄辩的模型来更新这一记录呢?我不希望任何用户无缘无故地一遍又一遍地请求数据库,只需要按下按钮来保存更改。我有一个 javascript功能,启用和禁用的保存按钮,根据是否有什么改变在页面,但我想知道是否有可能确保这种功能在服务器端也。我知道我可以通过检查记录是否有变化来自己完成它(意思是: 不需要依赖框架的内部功能) ,但是在这样做之前,我想知道 Laravel 雄辩模型是否已经处理好了这个问题,所以我不需要重新发明轮子。

这是我用来更新记录的方法:

$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();
162942 次浏览

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
}

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

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

At times you need to compare the newly changed value with the previous one and if you are looking for that here is the solution.

if (
$obj->isDirty('some_field_name') &&
$obj->some_field_name != $obj->getOriginal('some_field_name')
) {
// Make required changes...
}
});
}

The reference of the derived solution is here.

use only this:

Product::where('id', $id)->update($request->except(['_token', '_method']));