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

时间:2017-11-05 15:27:56

标签: mysql laravel eloquent laravel-eloquent

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

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

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

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

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

不确定我是否理解正确。

我基本上是在传递“条件”即。需要检查的字段是否唯一 - 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不会为我填写时间戳。

感谢任何提示!

2 个答案:

答案 0 :(得分:1)

查看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找到一个或多个项目时,它只会更新这些匹配项目的第一个结果。

记录所有查询并检查代码实际执行的操作。 Logging queries

使用updateOrCreate()会导致1次选择和1次更新或插入查询,因此共计2次。

答案 1 :(得分:0)

所以是的,我有这种感觉,而@Robert给了你证明。

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

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

我希望它适合你。