Laravel 检查相关模型是否存在

2022-08-30 06:29:03

我有一个雄辩的模型,它有一个相关的模型:

public function option() {
    return $this->hasOne('RepairOption', 'repair_item_id');
}

public function setOptionArrayAttribute($values)
{
    $this->option->update($values);
}

当我创建模型时,它不一定有相关的模型。当我更新它时,我可能会添加一个选项,或者不添加。

因此,我需要检查相关模型是否存在,分别更新它或创建它:

$model = RepairItem::find($id);
if (Input::has('option')) {
    if (<related_model_exists>) {
        $option = new RepairOption(Input::get('option'));
        $option->repairItem()->associate($model);
        $option->save();
        $model->fill(Input::except('option');
    } else {
       $model->update(Input::all());
    }
};

我正在寻找的代码在哪里。<related_model_exists>


答案 1

php 7.2+ 中,你不能在关系对象上使用,所以没有适用于所有关系的通用方法。请改用查询方法,@tremby如下所示:count

$model->relation()->exists()

适用于所有关系类型的通用解决方案(php 7.2 之前):

if (count($model->relation))
{
  // exists
}

这将适用于每个关系,因为动态属性返回 或 。两者都实现了.ModelCollectionArrayAccess

所以它是这样的:

单关系: hasOne / belongsTo / morphTo / morphOne

// no related model
$model->relation; // null
count($model->relation); // 0 evaluates to false

// there is one
$model->relation; // Eloquent Model
count($model->relation); // 1 evaluates to true

对多关系: hasMany / belongsToMany / morphMany / morphToMany / morphedByMany

// no related collection
$model->relation; // Collection with 0 items evaluates to true
count($model->relation); // 0 evaluates to false

// there are related models
$model->relation; // Collection with 1 or more items, evaluates to true as well
count($model->relation); // int > 0 that evaluates to true

答案 2

关系对象将未知方法调用传递到 Eloquent 查询生成器,该生成器设置为仅选择相关对象。该生成器反过来将未知方法调用传递到基础查询生成器

这意味着您可以直接从关系对象使用 exists()count() 方法:

$model->relation()->exists(); // bool: true if there is at least one row
$model->relation()->count(); // int: number of related rows

请注意:后面的括号是一个函数调用(获取关系对象),而不是Laravel为您设置的魔术属性getter(获取相关对象/对象)。relation->relation()->relation

在关系对象上使用该方法(即,使用括号)将比执行或(除非关系已经预先加载)快得多,因为它运行计数查询,而不是从数据库中提取任何相关对象的所有数据,只是为了对它们进行计数。同样,使用也不需要提取模型数据。count$model->relation->count()count($model->relation)exists

两者都适用于我尝试过的所有关系类型,因此至少,,,和。exists()count()belongsTohasOnehasManybelongsToMany


推荐