【问题标题】:What's the best way to get a row through a table in Laravel?在 Laravel 中通过表格获得一行的最佳方法是什么?
【发布时间】:2020-11-26 23:55:21
【问题描述】:

我的数据库中有以下表格:

我想列出 cmets 评分最高的视频,例如:

app/Helpers/function.php

function best_comment($data, $value = 'name') {
    $properties = array();

    foreach($data->episodes as $episode) {
        if(! isset($properties['id']) || $properties['id'] > $season->bestComment[0]->id) {
            $properties['id'] = $season->bestComment[0]->id;
            $properties['name'] = $season->bestComment[0]->name;
        }
    }
    
    if(! empty($properties)) {
        return $properties[$value];
    }
}

app/Video.php

public function episodes() {
    return $this->hasMany(Episode::class);
}

app/Episode.php

public function bestComment() {
    return $this->belongsToMany(Rating::class, 'comments', 'id')->orderBy('id', 'asc')->limit(1);
}

app/Http/Controllers/VideosController.php

public function index() {
    $videos = Videos::query();

    $videos->with('episodes');

    return view('videos.index')->with('videos', $videos->paginate(4));
}

资源/视图/视频/index.blade.php

@foreach($videos as $video)
    <div>
        <h5>{{ $video->title }}</h5>
        Best comment rating: {{ best_comment($video, 'name') }}
    </div>
@endforeach

我的解决方案有很多疑问。打印评分最高的评论的最佳方式是什么?

Laravel Sandbox

【问题讨论】:

  • 不要在问题上链接图片,将它们直接注入问题中
  • 请发布视频模型...并且,请通知我这里发表评论的 chenges,否则我将无法知道您已发布
  • 我已经扩展了描述。

标签: php mysql laravel


【解决方案1】:

这不是最佳解决方案,但应该可以。

首先从分页对象中获取Video模型的ID:

$ids = $videos-&gt;getCollection()-&gt;pluck('id');

然后使用它们加入其他表格,按视频分组并选择最高评分 ID。如果您的评级表中有其他列,您可能需要对此进行调整,也就是说,您可以比使用它们的主键更好地对它们进行排名。

$videoToRatingMap = Videos::query()
    ->whereIn('id', $ids)
    ->join('episodes', 'episodes.video_id', '=', 'videos.id')
    ->join('comments', 'comments.episode_id ', '=', 'episodes.id')
    ->join('ratings', 'ratings.id', '=', 'comments.rating_id')
    ->groupBy('videos.id')
    ->select('videos.id')
    ->selectRaw('max(ratings.id) as rating_id')
    ->get();

这将为您提供按 ID 和最高评论排名的视频地图。

这不会让您获得排名的名称,但是可以在单独的查询中完成:

$ratingNames = Rating::query()
    ->findMany($videoToRatingMap->pluck('rating_id'))
    ->pluck('name', 'id');

然后转换评分图以包含名称:

$videoToRatingMap->transform(function($video) use ($ratingNames){
    $video['rating_name'] = $ratingNames[$video['rating_id']];
    return $video;
})->keyBy('id');

这将为您提供一个集合,由视频 ID 键控,其中还包含评级 ID 及其名称。

一种更优化的方法是获取第一个查询并将整个查询包装到一个子查询中,这样您就可以再次加入评级表并获得名称。将以使单个查询更复杂为代价将查询减少一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 2011-07-05
    • 2015-06-05
    相关资源
    最近更新 更多