Laravel Eloquent更新,即使已进行更改


86

有什么方法可以使用雄辩的模型更新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();

3
为什么不启用数据库日志记录,然后检查日志,看看有什么查询雄辩当你做实际执行保存:你可能会感到惊喜
马克·贝克

4
请注意,Laravel模型具有一个dirty标志,该标志用于确定是否实际需要对数据库进行更新,并且通过将原始find列值与执行保存时的值进行比较来设置该标志
Mark Ba​​ker,2015年

@MarkBaker这是一个很好的提示!
user2755140

Answers:


176

您已经在做!

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

这是代码中的相关部分Illuminate\Database\Eloquent\Model@performUpdate

protected function performUpdate(Builder $query, array $options = [])
{
    $dirty = $this->getDirty();

    if (count($dirty) > 0)
    {
        // runs update query
    }

    return true;
}

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;
}

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

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

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

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

那很棒。谢谢。我不知道现在如何才能访问该脏标志以了解是否在未进行任何更改的情况下进行了更新尝试?我的意思是:该行动的回报?
user2755140 2015年

1
@DaseinA您可以使用isDirty()它。查看最新答案
lukasgeiter 2015年

2
对于那些阅读此书的人,请务必在使用之前检查出此答案isDirty()
Alex

1
getChanges()方法。检查我的答案stackoverflow.com/a/54132163/1090395
Mladen Janjetovic

FYIisDirty()将是true,如果你不投你的属性的权利。我有一个与数据库中的浮点数完全相同的浮点数,但是因为我用一个字符串设置了浮点数(例如,“ 10.50”而不是10.50),它将把它检测为更改并执行更新。
马丁·格拉夫


11

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

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

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


3
这实际上是我在寻找的答案,我忘记了这个名字 fill,以及如何将请求大量传递给它。谢谢!由于即时更新,我不需要传递ID,因此它已经存在$request->id
blamb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.