【问题标题】:laravel mass assignment on set attribute and except column设置属性和除列的 laravel 质量分配
【发布时间】:2019-05-11 06:39:31
【问题描述】:

我的数据库中有一个“full_name”列,但我的数据库中没有“first_name”和“last_name”列。

这是我的表格:

<form method="POST" action="">
    <input type="text" name="first_name">
    <input type="text" name="last_name">
</form>

这是我的模型:

class User extends Model
{
    protected $guarded = ['first_name', 'last_name'];

    public function setFullNameAttribute()
    {
        $this->attributes['full_name'] = $this->attributes['first_name'].' '.$this->attributes['last_name'];
    }
}

这是我的控制器类中的代码

public function store(StoreUser $request)
{
    $validated = $request->validated();
    $user = Auth::user();
    $user->update($validated);
}

我提交表单后,出现错误:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'first_name' in 'field list'

我知道这是什么原因,是因为$guarded = ['first_name', 'last_name']

但是如果我没有看守那些字段,就会报错:

"Undefined index: first_name"

我知道这是什么原因,因为我的数据库中没有“first_name”列。


所以我卡住了,不知道如何将“full_name”更新到数据库中, 并防止分配“first_name”和“last_name”字段。

PS,我不使用$user-&gt;save()是因为现实世界中有大量任务需要更新。

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    控制器的角色是让输入适应您的模型/存储库。

    你的模型应该只反映数据:

    class User extends Model
    {
        protected $guarded = ['full_name'];
    }
    

    你的控制器

    public function store(StoreUser $request)
    {
        $validated = $request->validated();
        $user = Auth::user();
        if (isset($validated['first_name']) && isset($validated['last_name'])) {
            $validated['full_name'] = $validated['first_name'].' '.$validated['last_name'];
        }
        unset($validated['first_name'], $validated['last_name']);
        $user->update($validated);
    }
    

    但如果你想继续使用你的方法,我建议你多收费用更新方法

    class User extends Model
    {
        protected $guarded = ['first_name', 'last_name'];
    
        /**
        * @param array $attributes
        * @param array $options
        * @return bool
        */
        public function update(array $attributes = [], array $options = [])
        {
            if (isset($attributes['first_name']) && isset($attributes['last_name'])) {
                $attributes['full_name'] = $attributes['first_name'].' '.$attributes['last_name'];
            }
            unset($attributes['first_name'], $attributes['last_name']);
            return parent::update($attributes, $options);
        }
    }
    

    【讨论】:

    • overwrite update 方法的思路不错,也就是说我可以在任何地方使用它,只要有'first_name'和'last_name',模型会自动生成'full_name'并插入数据库!
    • @Autodesk 认为 $guarded = ['first_name', 'last_name'];$fillable = ['full_name']; 不是同一个东西。更新了答案,但你真的应该使用第一个解决方案。否则你的代码中会出现很多异常。
    • @Autodesk 你知道 $guarded 不会阻止你像你正在做的那样分配 full_name 属性。它只会阻止它的批量分配。例如User::create(['full_name' =&gt; 'hi there'])new User(['full_name' =&gt; 'hi there'])。因此可以像使用 save() 方法一样使用它
    • $guarded 只对批量赋值有影响,update() 是批量赋值,所以update() 不会更新那些 $guarded 字段,但 save() 会更新 $guarded 字段,因为@987654333 @ 不是批量赋值。我说的对吗?
    • 绝对正确,忘了你用的是update()而不是save()
    【解决方案2】:

    最简单的解决方案是:

    class User extends Model
    {
        protected $fillable = ['full_name'];
    
    }
    

    存储功能如下:

    public function store(StoreUser $request)
    {
        $validated = $request->validated();
        $validated['full_name'] = $validated['first_name'].' '. $validated['last_name'];
        $user = Auth::user();
        $user->update($validated);
    }
    

    【讨论】:

    • 谢谢,它可以工作,但是如果以后需要更改,这意味着我必须在每个班级都修改它:(
    • protected $guarded = ['first_name', 'last_name']; 在您的示例中没有任何作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多