【问题标题】:Laravel 8 - firstOrCreate() doesn't return Default value set in the DBLaravel 8 - firstOrCreate() 不返回数据库中设置的默认值
【发布时间】: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() 以补充水分默认列

标签: sql laravel eloquent laravel-8


【解决方案1】:

阅读@dave 解决方案:

最后的代码应该是:

$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 开始关注整个流程
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 2015-02-20
    • 2014-12-24
    • 2021-11-19
    • 2023-02-24
    • 2017-02-18
    相关资源
    最近更新 更多