如何授权然后更新 Laravel 模型

Posted

技术标签:

【中文标题】如何授权然后更新 Laravel 模型【英文标题】:How to authorize then update a Laravel model 【发布时间】:2018-06-13 05:00:02 【问题描述】:

我正在调用这个控制器来更新模型:

public function update(Request $request, $id)
  
  $question = Question::find($id);
  $this->authorize('edit', $question); // uses Laravel's built-in Policy framework

  $updateArray = [
    'question' => $request->question,
    'type_based_id' => $request->type_based_id,
  ];

  //$question = Question::where('id', $id);
  $question = $question->update($updateArray);

  // Add the id into the array for return to the client
  $updateArray["id"] = $id;

  return ['message' => 'Question Updated', 'data' => $updateArray];


上面的代码在调用$question->update() 时会引发MassAssignmentException。如果我取消注释 $question = Question::where('id', $id); 它会起作用。

我做了一些记录,似乎 find() 返回了我的模型的一个实例 (App\Question),而 where() 返回了一个构建器 (Illuminate\Database\Eloquent\Builder)

如何在不发出两个单独的数据库请求的情况下同时满足 authorize() 和 update() 的要求?

谢谢!

【问题讨论】:

不太清楚你在问什么。授权与您的更新调用无关。 MassAssignmentException 通常意味着您传递的属性之一在模型中受到保护。 【参考方案1】:

它使用查询生成器工作的原因是它绕过了模型的质量分配检查。您正在运行自己的查询,而不是使用模型的更新方法。

Question::where()->update 是在查询生成器上调用更新,而不是在模型上。

当您已经拥有要更新的模型实例时,没有理由使用查询构建器,但这实际上并没有运行任何额外的 SQL 查询。


MassAssignmentException 通常意味着您传递的属性之一在模型中受到保护。要取消保护属性,请从 $guarded 属性中删除它们或将它们添加到模型的 $fillable 属性中。不要同时使用 $guarded 和 $fillable,您必须使用其中一个。在此处阅读完整文档:

https://laravel.com/docs/5.5/eloquent#mass-assignment

【讨论】:

谢谢 - 我已阅读大量作业文档,但误解了该术语的含义。 This answer 为我澄清了。【参考方案2】:

MassAssigntmentException 是由于您要更新的字段不是 fillable,因此无法分配,要实现这一点,您需要在 Question 类上设置这些字段。

public class Question

    protected $fillable = [
        'question',
        'type_based_id',
    ];

【讨论】:

以上是关于如何授权然后更新 Laravel 模型的主要内容,如果未能解决你的问题,请参考以下文章

1+X web中级 Laravel学习笔记——Eloquent ORM查询更新删除新增

我想自学laraver,请诸位前辈给一些建议,谢谢

larave学习笔记1-安装配置

Larave使用composer安装无反应,提示“Changed current directory to C:/Users/Administrator/AppData/Roaming/Compose

Larave使用composer安装无反应,提示“Changed current directory to C:/Users/Administrator/AppData/Roaming/Compose

如何通过多对多关系获取与同一张表相关的行 - Laravel