You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何授权后更新模型且避免两次数据库请求?

解决Laravel中模型实例update触发MassAssignmentException的问题

问题原因分析

你碰到的这个问题核心是Laravel批量赋值校验机制的差异:

  • 用Question::find($id)拿到的是模型实例,调用->update()时,Laravel会严格校验模型的$fillable(或$guarded)属性,只有在$fillable里声明的字段才能被批量赋值,否则就会抛出MassAssignmentException。
  • 而Question::where('id', $id)返回的是查询构造器,它的update()方法直接生成并执行SQL语句,不会经过模型层的批量赋值校验,所以不会报错,但这种方式跳过了模型的安全校验,并非最佳实践。

最优解决方案:配置模型的批量赋值字段

最规范且无需额外数据库查询的方式,就是在App\Question模型中添加$fillable属性,把允许批量更新的字段列进去:

// app/Question.php
class Question extends Model
{
    // 声明允许批量赋值的字段
    protected $fillable = ['question', 'type_based_id'];
}

修改后你原来的代码(用find()获取模型实例、授权后直接update)就能正常运行,既完成了授权校验,也只发起了一次数据库查询(find()那一次)。

其他可选方案(非必要不推荐)

如果出于特殊原因不想设置$fillable,可以试试以下方式,但要注意安全风险:

  1. 逐个赋值后用save()
    这种方式不依赖$fillable,但代码会稍显繁琐:

    public function update(Request $request, $id) {
        $question = Question::find($id);
        $this->authorize('edit', $question);
        
        $question->question = $request->question;
        $question->type_based_id = $request->type_based_id;
        $question->save();
        
        $updateArray = [
            'id' => $id,
            'question' => $request->question,
            'type_based_id' => $request->type_based_id,
        ];
        return ['message' => 'Question Updated', 'data' => $updateArray];
    }
    
  2. 基于已有模型用构造器update
    利用已获取的模型实例的主键构造查询,避免二次查询:

    public function update(Request $request, $id) {
        $question = Question::find($id);
        $this->authorize('edit', $question);
        
        $updateArray = [
            'question' => $request->question,
            'type_based_id' => $request->type_based_id,
        ];
        // 用已有模型的主键执行update,无需再次查询数据库
        Question::where('id', $question->id)->update($updateArray);
        
        $updateArray["id"] = $id;
        return ['message' => 'Question Updated', 'data' => $updateArray];
    }
    

    不过这种方式会跳过模型的批量赋值校验,同时也不会触发updated等生命周期钩子,所以除非特殊场景,优先推荐第一种方案。


内容的提问来源于stack exchange,提问作者Witt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:00:18