作为程序员一定要保持良好的睡眠,才能好编程

Laravel中firstOrCreate与firstOrNew及firstOrFail的区别

发布时间:2020-01-30


官方文档:

https://learnku.com/docs/laravel/6.x/eloquent/5176#b438f8


在日常开发的过程中,经常会遇到判断一条记录是否存在、存在更新、不存在新建记录这种场景,在 Laravel 中提供了方法支持,那么下面就看下具体的方法;

使用时请注意版本,下面介绍的函数 firstOrCreate 和 firstOrNew firstOrFail中使用


1、firstOrCreate


如果查询结果不存在,则会以后边的两个参数为基础,创建新的实例Model返回,并且将数据查询到数据中

小于 5.5 版本,只有一个参数
public function firstOrCreate(array $attributes)
{
    if (! is_null($instance = $this->where($attributes)->first())) {
        return $instance;
    }
    $instance = $this->model->newInstance($attributes);
    $instance->save();
    return $instance;
}

5.5 版本
public function firstOrCreate(array $attributes, array $values = [])
{
    // 判断是否存在,如果存在,返回实例
    if (! is_null($instance = $this->where($attributes)->first())) {
        return $instance;
    }

    // 不存在创建,此代码简化就是 $this->newModelInstance($attributes + $values)->save();
    return tap($this->newModelInstance($attributes + $values), function ($instance) {
        $instance->save();
    });
}


2、firstOrNew


如果查询的结果不存在,则会以 firstOrNew中传递的两个参数为基础,创建一个新的Model 实例返回,并不会保存到数据库中


小于 5.5 版本,只有一个参数
public function firstOrNew(array $attributes)
{
    if (! is_null($instance = $this->where($attributes)->first())) {
        return $instance;
    }
    return $this->model->newInstance($attributes);
}

5.5 版本
public function firstOrNew(array $attributes, array $values = [])
{
    if (! is_null($instance = $this->where($attributes)->first())) {
        return $instance;
    }
    return $this->newModelInstance($attributes + $values);
}

查看源码就更清楚 firstOrCreate 比 firstOrNew 多了 save 方法,两个方法都很实用,根据场景使用它。




2.firstOrNew
会尝试使用指定的属性在数据库中寻找符合的纪录。如果未被找到,将会返回一个新的模型实例。请注意 firstOrnew 返回的模型还尚未保存到数据库。你需要通过手动调用 save 方法来保存它

用法:

User::firstOrNew(['name' => 'Lisi']);
User::firstOrNew(['name' => 'Lisi'], ['age' => 20]); // 5.5及以上版本支持



3、firstOrFail

如果查询的方法不存在,则抛出一个异常信息


项目中用法:

$doctorLevel = DoctorModel::query()->with([
            'level' => function ($query) {
                $query->select('id', 'level_name');
            }
        ])->where('id','339856447067199853')->select(['id', 'doctor_level'])->firstOrFail();


返回结果:        
"message": "No query results for model [App\\Models\\Inquiry\\DoctorModel].",





Laravel firstOrNew 与 firstOrCreate 的区别

例如:


$item = App\Deployment::firstOrNew(

    ['name' => '问答小程序'], ['delayed' => 1]

);

firstOrNew 需要手动调用 save,才会保存到数据库。适合同时需要修改其他属性的场景。

firstOrCreate 会自动保存到数据库。适合不需要额外修改其他属性的场景。

注意:MassAssignmentException

firstOrCreate 一定要设置 model 的 fillable, 否则会报 MassAssignmentException 的错误。


参考: Laravel Model 的 fillable (白名单)与 guarded (黑名单)


即,create 受 fillable 的限制,但是 save 不受影响。







用法:

User::firstOrCreate(['name' => 'Lisi']);
User::firstOrCreate(['name' => 'Lisi'], ['age' => 20]);  // 5.5及以上版本支持



官方文档:

https://learnku.com/docs/laravel/6.x/eloquent/5176#b438f8