首页 > 解决方案 > Laravel API 资源,仅获取集合中最新出现的资源

问题描述

嗨,我正在 laravel 中为在线课程系统开发一个 api。在这个方案中,我有一个用户标准表、一个课程表和一个将课程和用户关联起来的数据透视表,他们根据这些数据注册每门课程。

最后这张表还携带了每个用户在课程中的进度相关的事件,即Subscribed、Progress x%、Completed、Approved,这样每个用户在course_users表中可以有多个条目。

到目前为止一切都清楚了,一切都很好,关键是在某个时刻我需要返回一个带有课程和指定用户信息的 json 对象,这可以通过以下方式使用资源收集清楚地实现:

CourseCollection.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;
use App\Http\Resources\CargoResource;

class CourseCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => CourseResource::collection($this->collection),
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}

课程资源.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class CourseResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title'=> $this->title,
            'description'=> $this->description,
            'price'=> $this->price,
            'users' => CourseUserResource::collection($this->whenLoaded('users'))
        ];
    }
}

CourseUserResource.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class CourseUserResource extends JsonResource
{

    public function toArray($request)
    {

        return [
            'course_id'=> $this-> course_id,
            'user_id'=> $this->user_id,
            'event'=> $this->event,
            'event_date' => $this->created_at->format('Y-m-d')
        ];
    }
}

要解决的问题是,通过这个方案,我获得了每个用户和课程的事件集合,但我需要的只是每个用户的最后一个事件,以了解他们与课程相关的状态。

我正在分析通过 sql 执行查询然后手动构建 json 对象的选项,但我想要一个“laravel 风格”的解决方案

欢迎任何想法!

EER图

添加了模型和控制器以进行澄清

class Course extends Model
{

    protected $fillable = [
        'title',
        'slug',
        'description',
        'course_category_id',
        'price',
        'published'
    ];

...

    public function history()
    {
        return $this->belongsToMany(CourseUser::class, 'course_id', 'id')->latest();
    }

    public function scopePublished($query)
    {
        return $query->where('published', 1);
    }

}

class CourseUser extends Model
{

    protected $fillable = [
        'course_id',
        'user_id',
        'event'
    ];

}

class SearchController extends ApiController
{

    public function search(Request $request)
    {
        $results = Course::with('history')
            ->published
            ->where('title', 'like', $request->filter['title'])
            ->where('description', 'like', $request->filter['description'])
            ->get();

        if (! count($results) > 0) {
            return $this->sendResponse(
                __('No results for your query.'),
                [
                    'code'=>204,
                    'message'=> __('There are no results for your search criteria.')
                ],
                204
            );
        }
        return new CourseCollection($results);
    }
}

标签: mysqllaraveleloquent

解决方案


推荐阅读