Laravel突变器没有匹配的数据库列
我正在寻找将突变器和登录器更新为中引入,但我似乎无法使其起作用。
我目前有一个与 morphmany
与设置的关系
对象的模型,该模型充当键值存储。作为速记,我正在使用突变器来设置一些更常用的设置。非常简化,看起来像这样:
class Item extends Model
public function setSomeSettingAttribute($value)
{
$key = "some_setting";
Setting::updateOrCreate(
["settable_id" => $this->id, "settable_type" => self::class, "key" => $key],
["value" => $value]
);
}
}
$m = Item::find(1);
// typically in a controller this would be $request->all()
$arr = ["some_setting" => 234];
$m->update($arr);
这可以正常工作,并且设置已更新。要注意的重要一点是,数据库中没有列,名为 some_setting
。
在新代码中,似乎突变器应该看起来像这样:
public function someSetting(): Attribute
{
$key = "some_setting";
return Attribute::make(
set: function ($value) use ($key): void {
Setting::updateOrCreate(
["settable_id" => $this->id, "settable_type" => self::class, "key" => $key],
["value" => $value]
);
}
);
}
但这是不起作用的。 Laravel试图将某些内容插入 some_setting
列中,从而导致SQL“未找到”错误。
有没有办法解决此问题,不涉及编辑我所有的控制器代码以删除伪造的列?或者,如果没有,旧的突变器语法是否以任何方式贬低了?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
laravel中的突变器,类似于演员设置雄辩的属性值。严格来说,写入数据库不是突变器的工作。相反,
属性
的设置器功能的结果将添加到模型的内部$属性
array。在您的情况下,由于setter函数没有返回任何内容,'some_setting'
键键 array设置为null
,执行更新时,导致Laravel尝试将null
写入本列。也就是说,如突变文档的多个属性。当您从设置器返回 empty 数组时,Laravel将将其视为属性数组,并且根本不会将任何内容添加到
$属性
属性中。这使您可以在不更改模型本身的任何属性的情况下应用副作用:但是,通常,当您要编辑这样的设置时,您将定义
settings
关系( morphmany 在这种情况下)并执行这样的更新:Mutators in Laravel, similar to casts, are meant to transform an Eloquent attribute value when it is set. Strictly speaking, it is not the job of a mutator to write to the database. Rather, the result of an
Attribute
's setter function gets added to the model's internal$attributes
array. In your case, since the setter function didn't return anything, the'some_setting'
key in the$attributes
array was set tonull
, causing Laravel to attempt writingnull
to this column when performing the update.That said, it is possible to return an array of attribute names and values, as described in the Mutating Multiple Attributes section of the documentation. When you return an empty array from the setter, Laravel will treat this as an array of attributes, and it won't add anything to the
$attributes
property at all. This allows you to apply side effects without altering any attribute on the model itself:Typically though, when you want to edit a setting like this, you'd define a
settings
relationship (morphMany, in this case) and perform the update like this: