php Laravel Eloquent 更新仅在进行更改时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28866500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:06:50  来源:igfitidea点击:

Laravel Eloquent update just if changes have been made

phplaraveleloquent

提问by user2755140

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 javascriptfunction 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.

如果对该记录进行了更改,是否有任何方法可以使用 eloquent 模型更新 Laravel 中的记录?我不希望任何用户无缘无故地一遍又一遍地请求数据库,只需点击按钮即可保存更改。我有一个javascript功能可以根据页面中的某些内容是否发生更改来启用和禁用保存按钮,但我想知道是否可以确保在服务器端也执行这种功能。我知道我可以自己完成它(意思是:不诉诸框架的内部功能)只是通过检查记录是否有变化,但在这样做之前,我想知道 Laravel eloquent 模型是否已经处理好了那个,所以我不需要重新发明轮子。

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

回答by lukasgeiter

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.

save()将检查模型中的某些内容是否已更改。如果没有,它将不会运行数据库查询。

Here's the relevant part of code in Illuminate\Database\Eloquent\Model@performUpdate:

这是代码的相关部分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 originalwhen the model is created. This is done in the syncOriginal()method:

getDirty()方法只是将当前属性与original创建模型时保存的副本进行比较。这是在syncOriginal()方法中完成的:

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

如果你想检查模型是否脏,只需调用isDirty()

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

Or if you want to check a certain attribute:

或者,如果您想检查某个属性:

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

回答by Mladen Janjetovic

You can use getChanges()on Eloquent model even after persisting.

getChanges()即使在持久化之后,您也可以在 Eloquent 模型上使用。

回答by Ahmad Yousef

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:

我喜欢添加此方法,如果您使用的是编辑表单,则可以使用此代码来保存update(Request $request, $id)函数中的更改:

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

请记住,您必须使用相同的列名命名您的输入。该fill()功能将为您完成所有工作:)