确定Laravel查询中是否存在关系

时间:2018-08-04 17:29:04

标签: php laravel eloquent

我已经在工作中继承了Laravel 5项目,并且想知道我应该如何检查相关模型的存在以避免空异常。

BlockDate模型

class BlockDate extends Model {
    public function claims()
    {
         return $this->belongsToMany(User::class);
    }
}

用户模型

class User extends Model {
    public function blocks()
    {
         return $this->belongsToMany(BlockDate::class);
    }
}

数据透视表

$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');


$table->unsignedInteger(block_date_id');
$table->foreign('block_date_id')->references('id')->on(block_dates);

用户可以为休假请求声明日期范围。但是,用户可能没有要求,也可能没有要求日期。我目前正在使用

if ($user->blocks->count() > 0) {
    $dates = $user->blocks->sortByDesc('created_at');
    // more logic here....
}

我不喜欢在任何地方都使用count,有没有办法合并支票,例如:

// I don't know what hasClaimedDates might be
$dates = $user->hasClaimedDates()->blocks->sortByDesc('created_at');

2 个答案:

答案 0 :(得分:2)

您可以使用实际的关系方法代替魔术访问器:

$sortedDates = $user->blocks()->latest()->get();

如果未建立任何关系,这将为您提供一个空集合,但排序不会失败。

注意:在这种情况下,latest()orderBy('created_at', 'desc')等效。


顺便说一句,如果您使用$user->blocks->count(),它将首先将所有相关模型加载到内存中,然后依靠该关系。如果您以后要使用相关模型,那很好。但是,如果不这样做,而只计算它们,那就浪费了资源。在这种情况下,$user->blocks()->count()的性能更高,因为它执行的数据库查询仅返回一个数字。考虑到这一点,尤其是在您有很多相关模型的地方。

答案 1 :(得分:0)

Laravel提供了一种optional帮助方法来防止出现null:

// will return either a collection or null
$dates = optional($user->blocks)->sortByDesc('created_at');