Laravel检查是否存在相关模型

Tom*_*ald 128 php laravel eloquent laravel-4 laravel-5

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

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

public function setOptionArrayAttribute($values)
{
    $this->option->update($values);
}
Run Code Online (Sandbox Code Playgroud)

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

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

$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());
    }
};
Run Code Online (Sandbox Code Playgroud)

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

Jar*_*zyk 170

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

$model->relation()->exists()
Run Code Online (Sandbox Code Playgroud)

处理所有关系类型的通用解决方案(pre php 7.2):

if (count($model->relation))
{
  // exists
}
Run Code Online (Sandbox Code Playgroud)

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

所以它是这样的:

单一关系: 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
Run Code Online (Sandbox Code Playgroud)

对多关系: 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
Run Code Online (Sandbox Code Playgroud)

  • @CurvianVynes不,它没有.`Collection`有自己的方法`isEmpty`,但泛型`empty`函数为对象返回false(因此不适用于空集合). (7认同)
  • 当关系尚未设置关联时,“count($model-&gt;relation)”对“morphTo”不起作用。外部 id 和类型为 null,Laravel 构建的数据库查询是伪造的并引发异常。我使用 `$model-&gt;relation()-&gt;getOtherKey()` 作为解决方法。 (2认同)
  • 它将在PHP 7.2上中断,返回:`count():参数必须是一个数组或实现Countable的对象。 (2认同)

tre*_*mby 69

Relation对象通过未知方法调用通过一个锋查询生成器,其被设置为仅选择相关的对象.该Builder又将未知方法调用传递给底层查询Builder.

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

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

注意以下括号relation:->relation()是函数调用(获取关系对象),而不是->relationLaravel为您设置的魔术属性获取器(获取相关对象/对象).

count在关系对象上使用该方法(即使用括号)将比执行$model->relation->count()或更快count($model->relation)(除非关系已被急切加载),因为它运行计数查询而不是拉动任何相关对象的所有数据从数据库中,只是为了计算它们.同样,使用exists也不需要拉模型数据.

无论exists()count()工作在我已经尝试了所有关系类型,所以至少belongsTo,hasOne,hasMany,和belongsToMany.

  • 谢谢,这应该是公认的答案! (4认同)
  • 至少在 Laravel 6.x 中,“exists”对于不存在的“morphTo”关系不起作用。它收到 SQL 错误。 (2认同)

Haf*_*ari 18

我更喜欢使用exists方法:

RepairItem::find($id)->option()->exists()

检查相关模型是否存在.它在Laravel 5.2上运行良好

  • +1;即使关系表中没有项目, count($model-&gt;relation) 在 Laravel 5.2 中为我返回 true 。-&gt;exists() 就可以了。 (2认同)

Hem*_*ela 9

Php 7.1之后,接受的答案将不适用于所有类型的关系.

因为根据类型的关系,Eloquent将返回a Collection,a ModelNull.在Php 7.1中 count(null)会抛出一个error.

因此,要检查是否存在关系,您可以使用:

对于单身关系:例如hasOnebelongsTo

if(!is_null($model->relation)) {
   ....
}
Run Code Online (Sandbox Code Playgroud)

对于多个关系:例如:hasManybelongsToMany

if ($model->relation->isNotEmpty()) {
   ....
}
Run Code Online (Sandbox Code Playgroud)

  • 非常适合我!如果我急切加载关系并在结果的 foreach 循环中执行 -&gt;count(),即使它们在模型中急切加载,它也会为每个项目生成一个 SQL 查询。使用 !is_null($model-&gt;relation) 是最快且 SQL 友好的方法。非常感谢。 (2认同)

小智 6

我用于单一关系:hasOnebelongsTomorphs

if($model->relation){ 
 ....
}
Run Code Online (Sandbox Code Playgroud)

因为如果条件为空,则这将为假。

对于多重关系:hasMany,belongsToManymorphs

if ($model->relation->isNotEmpty()) {
   ....
}
Run Code Online (Sandbox Code Playgroud)