laravel UPDATE方法如何工作

时间:2018-01-12 11:31:11

标签: php laravel-5.4

我正在研究这个用户可以上传头像图像的laravel项目。我的users表还没有任何列存储文件位置。所以我在phpunit中按照laracast中的TDD系列测试了这个。

文件成功上传并移动到服务器中的所需位置后,我在经过身份验证的用户上调用了更新方法,如下所示:

$user = auth()->user();
$user->update(['avatar_location' => 'avatars/avatar.jpg']);

请注意,users表上还没有 avatar_location 。我预计这会失败,但事实并非如此。我试图找出发生了什么,所以我跟着模型类中的 update()方法:

//file Illuminate/Database/Eloquent/Model.php

public function update(array $attributes = [], array $options = [])
{
    //dd($attributes);     //prints 'avatar_location"=>"avatars/avatar.jpg'
    if (! $this->exists) {
        //dd($attributes);
        return false;
    }
    return $this->fill($attributes)->save($options);
}

直到这一点,dd($属性)打印传递给update()方法的值。 所以我跟着使用属性参数调用的 fill()方法。但是,当我从fill()方法内部转储收到的参数时,我没有看到我传递的key =>值对。相反,它显示了用户的其他属性:

 /**
 * Fill the model with an array of attributes.
 *
 * @param  array  $attributes
 * @return $this
 *
 * @throws \Illuminate\Database\Eloquent\MassAssignmentException
 */
public function fill(array $attributes)
{
    //dd($attributes);

    //does not print 'avatar_location"=>"avatars/avatar.jpg'
    //rather, prints:
    //array:4 [
    //  "name" => "Armand Mraz"
    //  "email" => "akautzer@example.net"
    //  "password" =>         "$2y$10$h7OG9/Toh31MsyFQc8lfg.wHeQC7maP4Bh37bea.DXU//IuRuXZi."
    //  "remember_token" => "X0udISwEEM"
    ]

    $totallyGuarded = $this->totallyGuarded();

    foreach ($this->fillableFromArray($attributes) as $key => $value) {
        $key = $this->removeTableFromKey($key);

        // The developers may choose to place some attributes in the "fillable" array
        // which means only those attributes may be set through mass assignment to
        // the model, and all others will just get ignored for security reasons.
        if ($this->isFillable($key)) {
            $this->setAttribute($key, $value);
        } elseif ($totallyGuarded) {
            throw new MassAssignmentException($key);
        }
    }

    return $this;
}

我花了很多时间试图找出原因?

  1. 任何人都可以解释一下吗?
  2. 即使我尝试更新不存在的列,为什么更新方法没有失败?
  3. 谢谢,Yeasir

1 个答案:

答案 0 :(得分:0)

当您更新对象时,Laravel会尝试匹配数据数组的键和可填充字段列表。不考虑可填写字段中缺少的所有密钥/ valye对。这就是为什么它没有失败的原因。

您必须更新用户模型中的可填写字段列表(属性$ fillable)。

查看documentation

如果您在可填写字段列表中添加avatar_location并且该字段不存在,则在这种情况下,它将引发异常。