如何在话题列表中实现每条话题 附带 该话题的最新的 3 条评论并且展示在列表中?

$topics = Topic::with(['replies'=>function($query){
   $query->orderBy('id');
}])->get();

加上take之后,replies=>null

$topics = Topic::with(['replies'=>function($query){
   $query->orderBy('id')->take(3);
}])->get();

with里面不能加take方法吗?

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 2

我做过这样的需求,当时考虑到我的业务列表流量很大,我的做法是在发评论时候以话题id为键做一个缓存,然后在列表数据出出来时候,组装对应的评论数据

5年前 评论
长日将尽

在 Fractal 官方文档中,提供了解决方法。需要在具体的 include 方法中添加第二个参数 ParamBag,并修改代码 ,而 URL 的构成类似于: ?include=comments:limit(5|1):order(created_at|desc) ,文档也提供了示例代码,具体请参考(在页面最下方的位置): Transformers - Fractal
根据文档, 我修改 TopicTransformer ,代码如下:

<?php

namespace App\Transformers;

use App\Models\Topic;
use League\Fractal\ParamBag;
use League\Fractal\TransformerAbstract;

class TopicTransformer extends TransformerAbstract
{
    // 可以包含/嵌套的额外资源
    protected $availableIncludes = ['user', 'category', 'replies'];

    private $validParams = ['limit', 'order'];

    public function transform(Topic $topic)
    {
        return [
            'id' => $topic->id,
            'title' => $topic->title,
            'body' => $topic->body,
            'user_id' => (int)$topic->user_id,
            'category_id' => (int)$topic->category_id,
            'reply_count' => (int)$topic->reply_count,
            'view_count' => (int)$topic->view_count,
            'last_reply_user_id' => (int)$topic->last_reply_user_id,
            'excerpt' => $topic->excerpt,
            'slug' => $topic->slug,
            'created_at' => $topic->created_at->toDateTimeString(),
            'updated_at' => $topic->updated_at->toDateTimeString(),
        ];
    }

    public function includeUser(Topic $topic)
    {
        return $this->item($topic->user, new UserTransformer());
    }

    public function includeCategory(Topic $topic)
    {
        return $this->item($topic->category, new CategoryTransformer());
    }

    public function includeReplies(Topic $topic, ParamBag $params = null)
    {
        if ($params === null) {
            return $topic->replies;
        }

        // Optional params validation
        $usedParams = array_keys(iterator_to_array($params));
        if ($invalidParams = array_diff($usedParams, $this->validParams)) {
            throw new \Exception(sprintf(
                'Invalid param(s): "%s". Valid param(s): "%s"',
                implode(',', $usedParams),
                implode(',', $this->validParams)
            ));
        }

        // Processing
        list($limit, $offset) = $params->get('limit');
        list($orderCol, $orderBy) = $params->get('order');

        $replies = $topic->replies()
            ->take($limit)
            ->skip($offset)
            ->orderBy($orderCol, $orderBy)
            ->get();

        return $this->collection($replies, new ReplyTransformer());
    }
}

然后使用 postman 请求 URL :http://{{host}}/api/topics?include=user,category,replies:limit(3|0):order(created_at|desc)。成功获取话题列表并且附带最新的 3 条评论,截图如下:

file

不过这样依然会重复查询数据库:

file

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!