Eloquent updateOrCreate() 覆盖所有行 - 试图理解它

Eloquent updateOrCreate() overwrites all rows - trying to understand it

我在理解 updateOrCreate Eloquent 方法时遇到问题。

我有一个简单的数据库,我每隔 x 分钟从 API 和 运行 中保存信息。

如果数据库中不存在该行,我需要做的是执行 INSERT,否则只需执行 UPDATE 并更新已更改的数据。

我们如何在 Laravel 中实现此功能?

这是我现在所拥有的,但是它会在所有行中重写相同的数据。

不确定我是否理解正确。

我基本上是在传递 "condition" 即。需要检查的字段是否唯一 - campaign_id+variation_id 应该是唯一的。 (它由 MySQL 中的 UNIQUE 键支持)和我的数据数组:

$data = [
    'campaign_id' => $variation['campaign_id'],
    'variation_id' => $variation['variation_id'],
    'name' => $variation['name'],
    'description' => $variation['description'],
];

MyModel::updateOrCreate( ['campaign_id' => $variation['campaign_id'], 'variation_id' => 
$variation['variation_id'] ], $data);

它似乎与查询生成器方法 updateOrInsert 一起工作,但我想用 Eloquent 实现它,认为这很容易。 Plus Query Builder 没有为我填写时间戳。

感谢任何提示!

查看 Laravel 的来源,updateOrCreate() 在水下使用 firstOrNew($attributes)

public function updateOrCreate(array $attributes, array $values = [])
{
    return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
        $instance->fill($values)->save();
    });
}

Source

因此,当根据 $attributes 找到 1 个或多个项目时,它只会更新那些匹配项目的第一个结果。

记录您的所有查询并检查您的代码实际在做什么。 Logging queries

使用 updateOrCreate() 应该会产生 1 个 select 和 1 个更新或插入查询,所以总共有 2 个。

是的,我有这种感觉,@Robert 给了你证据。

你只需要通过这种方式将模型的 $primaryKey 设置为复合值:

protected $primarykey = ['campaign_id', 'variation_id']; 

希望它对你有用。