Laravel仅获得第一个相关模型

时间:2018-12-10 20:47:42

标签: php laravel relation

我想得到第一个相关模型。但这仅适用于集合中的第一个模型。第二个是空的。

我找到了this的答案,但没有找到解决方法。

我怎么只能得到第一个相关模型?

$querybuilder->with([
    'messages' => function ($query) {
        $query->orderBy("created_at", "DESC");
        $query->limit(1);
    }
]);

2 个答案:

答案 0 :(得分:1)

您可以使用HasOne关系:

class Conversation extends Model {
    public function latestMessage() {
        return $this->hasOne(Message::class)->latest();
    }
}

$querybuilder->with('latestMessage');

请注意,这仍然会从数据库中获取所有消息。然后,它会丢弃“旧”文件。

如果仅通过获取最新消息来提高性能,可以使用我创建的以下软件包:https://github.com/staudenmeir/eloquent-eager-limit

该软件包允许您将limit()应用于该关系:

class Conversation extends Model {
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

    public function latestMessage() {
        return $this->hasOne(Message::class)->latest()->limit(1);
    }
}

答案 1 :(得分:0)

您的with()实际上创建了几个查询,最后一个查询有限制,因此行为(正确)。您可以使用\DB::enableQueryLog();,运行查询,然后使用\DB::getQueryLog();查看查询的构建方式。

如果您想对每个模型项施加限制,则可以获取所有项并对其进行迭代以获取一个或多个相关模型项

这不是在sql中完成的,而是在php(laravel收集方法)中完成的,如果您在sql中需要它,则可以加入相关模型并根据需要进行设置。

如果您有大量数据,这将导致性能问题,但如果不这样做,将非常方便。

$result = \App\YourModel::all()
    ->map(function ($item) {
        return $item->YourRelatedModel()
            ->orderBy('someField')
            ->first();
    });

我忘记了...上面的方法仅返回相关模型的项目,如果您还希望可以使用父模型

$result = \App\YourModel::all()
    ->map(function ($item) {
        $item->YourRelatedModelName = $item
            ->YourRelatedModel()
            ->orderBy('someField')
            ->first();

        return $item;
    });