使用 XXModel::query()->updateOrCreate() 查询语句提示未找到 id 列?

使用updateOrCreate查询:
使用XXModel::query()->updateOrCreate() 查询提示未找到 id 列?

当数据库不存在指定数据时,并不会报错,且会准确的插入数据;
当数据库存在指定数据时,抛出了这个异常,且数据并不会被修改:

使用XXModel::query()->updateOrCreate() 查询提示未找到 id 列?

Migration 文件:
使用XXModel::query()->updateOrCreate() 查询提示未找到 id 列?

经过发现,在Model文件中修改protected $primaryKey = ''的值为已有列名(email、code)就不会报错,改为其他的字符或者保持默认的$primaryKey="id"值就会报错。

使用XXModel::query()->updateOrCreate() 查询提示未找到 id 列?

Migration文件中并未加入主键,出现这个问题是什么原因?
如何在没有主键的情况下使用updateOrCreate()方法才不会出现这种异常?

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

@long0 回答的你的第二个问题~

源码大法好!

public function updateOrCreate(array $attributes, array $values = [])
{
    // 其实是先firstOrNew,拿到实例后再save。
    // 简单分析一下,关键在于,如果数据库中存在和$attributes匹配的记录,那么调用
    // $model->save()就相当于调用了 `$model->update()` ,这时候就会使用模型主键了!
    // 而你又没有主键...这就很尴尬,不报错就奇怪啦
    return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
        $instance->fill($values)->save();
    });
}

public function firstOrNew(array $attributes, array $values = [])
{
    // 先获取,如果存在$attributes条件一样的实例,就返回实例
     if (! is_null($instance = $this->where($attributes)->first())) {
         return $instance;
     }

     return $this->newModelInstance($attributes + $values);
}

protected function performUpdate(Builder $query)
{
    // ...
    if (count($dirty) > 0) {
        $this->setKeysForSaveQuery($query)->update($dirty);
        // ...
    }
    return true;
}

protected function setKeysForSaveQuery(Builder $query)
{
    // 看到么~执行update的时候,是要使用主键的,所以你不能脱离主键
    $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
    return $query;
}
3年前 评论
long0 (楼主) 3年前
讨论数量: 2
panda-sir

file 这就是原因

3年前 评论
long0 (楼主) 3年前

@long0 回答的你的第二个问题~

源码大法好!

public function updateOrCreate(array $attributes, array $values = [])
{
    // 其实是先firstOrNew,拿到实例后再save。
    // 简单分析一下,关键在于,如果数据库中存在和$attributes匹配的记录,那么调用
    // $model->save()就相当于调用了 `$model->update()` ,这时候就会使用模型主键了!
    // 而你又没有主键...这就很尴尬,不报错就奇怪啦
    return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
        $instance->fill($values)->save();
    });
}

public function firstOrNew(array $attributes, array $values = [])
{
    // 先获取,如果存在$attributes条件一样的实例,就返回实例
     if (! is_null($instance = $this->where($attributes)->first())) {
         return $instance;
     }

     return $this->newModelInstance($attributes + $values);
}

protected function performUpdate(Builder $query)
{
    // ...
    if (count($dirty) > 0) {
        $this->setKeysForSaveQuery($query)->update($dirty);
        // ...
    }
    return true;
}

protected function setKeysForSaveQuery(Builder $query)
{
    // 看到么~执行update的时候,是要使用主键的,所以你不能脱离主键
    $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
    return $query;
}
3年前 评论
long0 (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!