Laravel 8 - firstOrCreate() 不返回数据库中设置的默认值
Posted
技术标签:
【中文标题】Laravel 8 - firstOrCreate() 不返回数据库中设置的默认值【英文标题】:Laravel 8 - firstOrCreate() doesn't return Default value set in the DB 【发布时间】:2021-01-20 04:56:03 【问题描述】:我的 mysql DB 将字段 formed_id
的默认值设置为 0
:
`former_id` bigint(20) NOT NULL DEFAULT 0
当我使用firstOrCreate()
方法插入新记录时,我没有设置formed_id
:
$record = Record::firstOrCreate(
[
"name" => "myName",
"nick" => "myNick",
]
);
然后输出返回:
"id": 10,
"name" => "myName",
"nick => "myNick",
"created_at" => "2020-10-01 00:00:00",
"updated_at" => "2020-10-01 00:00:00",
不包含设置为默认值的former_id
字段0
。
要获取输出模型中的所有文件,我需要执行第二次查询:
$record = Record::firstOrCreate(
[
"name" => "myName",
"nick => "myNick",
]
);
$fullRecord = Record::find($record->id)
在这种情况下,输出正确返回:
"id": 10,
"name" => "myName",
"nick => "myNick",
"former_id" => 0,
"created_at" => "2020-10-01 00:00:00",
"updated_at" => "2020-10-01 00:00:00",
我不喜欢这个解决方案,因为我需要执行两个查询而不是一个;有没有办法直接从 firstOrCreate()
插入中获取所有字段?
谢谢。
【问题讨论】:
插入后尝试刷新模型。$record = Record::firstOrCreate($details)->refresh();
您是手动创建表还是使用迁移文件?如果您使用了迁移文件,请将其代码添加到您的问题中。
@Prodiger 我试过->refresh()
但它是一样的,总是执行两个查询。 @Rwd 是的,这些表是手动创建的;我正在使用现有的数据库。没有使用 Laravel 迁移。
firstOrNew()
方法中也会发生同样的事情
我在不需要时阻止第二次查询的方法是检查 $record->wasRecentlyCreated
是否为 true
,如果是,然后运行 $record->refresh()
以补充水分默认列
【参考方案1】:
阅读@dave 解决方案:
Laravel 8 - firstOrCreate() doesn't return Default value set in the DB最后的代码应该是:
$record = Record::firstOrCreate(
[
"name" => "myName",
"nick" => "myNick",
]
);
if ($record->wasRecentlyCreated)
$record->refresh();
【讨论】:
【参考方案2】:这确实是正确的行为。默认情况下,在创建模型后直接获取模型可能非常低效。
在您的情况下,您可以将$attributes
属性添加到您的模型中,以实现默认属性并避免进行其他查询。
/**
* The model's attributes.
*
* @var array
*/
protected $attributes = [
'former_id' => 0,
];
【讨论】:
mmhh... 但我不喜欢这个解决方案,因为我需要将数据库中的默认字段与 Laravel 项目保持一致。返回字段id
、created_at
和updated_at
;为什么返回所有字段效率低?
这是低效的,因为您将执行两个查询。 INSERT
和 SELECT
。每当您一次创建多个时,这将很快加起来。但实际上,也许这不适用于您的情况。关于在一个地方有默认值。您可以将此添加到您的迁移->default((new Record)->former_id)
。就我个人而言,我更愿意在迁移中保留这个硬编码。迁移是您数据库的历史记录。
好的,但是id
、created_at
和updated_at
如何从数据库中检索? SELECT
?
id
是使用lastInsertId
检索的。 created_at
和 updated_at
都由 updateTimestamps
设置。您可以从Builder@create
开始关注整个流程以上是关于Laravel 8 - firstOrCreate() 不返回数据库中设置的默认值的主要内容,如果未能解决你的问题,请参考以下文章
在 Laravel 中,有没有办法找出是不是创建了 `firstOrCreate` 或者是不是找到了行?
laravel中firstorcreate和updateorcreate的操作区分
Laravel 5 firstOrCreate 保持创建甚至设置唯一的字段