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 项目保持一致。返回字段idcreated_atupdated_at;为什么返回所有字段效率低? 这是低效的,因为您将执行两个查询。 INSERTSELECT。每当您一次创建多个时,这将很快加起来。但实际上,也许这不适用于您的情况。关于在一个地方有默认值。您可以将此添加到您的迁移->default((new Record)->former_id)。就我个人而言,我更愿意在迁移中保留这个硬编码。迁移是您数据库的历史记录。 好的,但是idcreated_atupdated_at 如何从数据库中检索? SELECT? id 是使用lastInsertId 检索的。 created_atupdated_at 都由 updateTimestamps 设置。您可以从Builder@create 开始关注整个流程

以上是关于Laravel 8 - firstOrCreate() 不返回数据库中设置的默认值的主要内容,如果未能解决你的问题,请参考以下文章

laravel中firstOrCreate的使用

在 Laravel 中,有没有办法找出是不是创建了 `firstOrCreate` 或者是不是找到了行?

laravel中firstorcreate和updateorcreate的操作区分

Laravel 5 firstOrCreate 保持创建甚至设置唯一的字段

Laravel firstOrNew 与 firstOrCreate 的区别

Laravel FirstOrCreate和Save()重复输入