如何获得至少有 N 个相关的多个 `hasmany` 模型的随机模型

How to get a random model with at least N related of multiple `hasmany` models

我正在尝试结合两个功能: - 获得一个随机模型 - ...但前提是它至少有 1 个相关模型

我的 URL 是 entity/random 并且下面的代码运行良好:

    if ($entityid == 'random') {
        $random = Entity::all()->random(1);
        return Redirect::to(trans('routes.entities') . '/' . $random->id);
    }

现在,我的 Entity 模型定义了两个关系:

public function comments()
{
    return $this->hasMany('App\Models\Comment', 'entity_id');
}

public function sources()
{
    return $this->hasMany('App\Models\Source', 'entity_id');
}

定义它们后,我可以通过 $object->comments->count() 或通过 $object->sources->count() 获取相关评论的数量。 我的数据库是 MySQL.

我的大部分 Entities 都没有评论或来源。

灵感来自 Laravel Querying Relations Model::has('relation') doesn't work 我能够得到一个至少有 2 条评论的随机模型:

$random = Entity::has('comments', '>=', DB::raw(2))->get()->random(1);
// produces an Entity with at least 2 comments

待办事项

如何仅在两个关系计数(sourcescomments)中至少有一个至少为 2 时才选择随机模型。 也许像 orHas 这样的东西存在?

是的,有一个orHas方法。

你可以这样使用它:

$random = Entity::has('comments', '>=', 2)->orHas('sources', '>=', 2)->get()->random(1);

一些其他注意事项:

has() 语句不需要 DB::raw() 语法。需要这种语法的 sqlite 数据库曾经有一个错误,但是自 Laravel 4.1.25.

以来已经解决了

此外,您可能想要更改获取随机实体的方式。使用您当前的代码,您将检索符合条件的每条记录,并为每条记录创建一个完整的 Entity 对象。您拥有的实体记录越多,这段代码就会变得越慢。我会建议这样的事情:

$id = Entity::has('comments', '>=', 2)->orHas('sources', '>=', 2)->lists('id')->random(1);

$random = Entity::find($id);

首先,您使用 lists() 方法获取所有符合条件的实体的 ID。截至Laravel 5.2、lists()returns一个集合。在该 id 集合上使用 random() 方法来选择一个要获取的 id。然后,find()那个id,所以只创建了一个Entity对象。