【问题标题】:Laravel MassAssignmentException from firstOrNew by idLaravel MassAssignmentException from firstOrNew by id
【发布时间】:2017-04-14 18:30:00
【问题描述】:

我正在尝试使用 Laravel 的 firstOrNew 方法保存数据,这会产生 MassAssignmentException 错误。

我不明白为什么firstOrNew 方法会触发批量分配异常,因为它只是查看数据库,而不是尝试保存任何内容。来自the docs

firstOrNew 方法,如 firstOrCreate 将尝试定位一个 记录在数据库中匹配给定的属性。但是,如果一个 未找到模型,将返回一个新的模型实例。注意 firstOrNew 返回的模型尚未持久化到 数据库。

那么,为什么我的代码应该抛出 MAE:

$tour = Tour::firstOrNew(array('id' => $this->request['id']));

据我了解,上述代码所说的基本上是“查看数据库中是否有具有该 ID 的行,如果有,则返回该行,如果没有,则创建一个具有相关的新对象特性”。它没有保存任何数据,这是什么问题?

请注意,仅当行不存在时才会发生错误。

【问题讨论】:

  • 您正在尝试使用 ID 创建对象。在您的情况下这可能没问题,但通常 ID 的自动递增,因此您不想创建特定的。我会首先通过另一个属性来创建一个对象——如果名称存在就抓取它,否则创建一个具有该名称的对象。您也可以考虑查找听起来更合适的 findOrFail laravel.com/docs/5.3/eloquent#retrieving-single-models - 是否存在具有此 ID 的对象?如果是则get,否则抛出异常
  • 谢谢,虽然findOrFail 可能不合适,因为根据文档它会自动发送 404,这是我不想要的。 ID 确实是自动递增的,并且是唯一保证唯一的列,这就是我想使用它的原因。不知道如何做到这一点......
  • 是的,我听到了。 Alexey Mezenin 的回答涵盖了它失败的所有原因。如果您想轻松骑行,我很确定$tour = Tour::find($this->request['id']); if( ! $tour) $tour = new Tour; 将是到达同一个地方的一种非常轻松的方式。祝你好运!
  • 是的,这将是一个快速的解决方案。我想除了自动增强 ID 之外,我还将在我的表中实现一个随机生成的 UID 列,因为我可以看到这个问题再次出现。感谢您的帮助。

标签: laravel laravel-5 mass-assignment


【解决方案1】:

firstOrNew() 使用 newInstance() 使用构造函数创建新模型。 Constructor uses fill() 方法是质量分配。这就是您遇到异常的原因。

所以,你需要设置$fillable数组来使用firstOrNew()

【讨论】:

  • 啊,好的。 构造函数使用填充()方法,即质量分配。我猜这就是关键。
【解决方案2】:

当您没有在模型中定义可填充或受保护的字段时,会发生 MassAssignmentException

$guarded = [];
$fillable = ['explicitlydefinedfield'];

PS:您复制的文字准确地说明了正在发生的事情......它没有找到记录并正在尝试创建一个新记录。

firstOrNew ... 新

【讨论】:

  • 谢谢,我知道设置 guardedfillable 属性,我只是不明白为什么当数据没有被“持久化”(即保存)到数据库
  • 我认为下一个答案更好地解决了这个问题:)
猜你喜欢
  • 2018-04-08
  • 2014-04-12
  • 1970-01-01
  • 2011-04-06
  • 2014-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多