Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

320
Vistas
What's the best way to get a row through a table in Laravel?

I have the following tables in my database:
Database relationship

I would like to list videos with the best rating of comments, like this:
List database content

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));
}

resources/views/videos/index.blade.php

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

With my solution there are many queries. What's the best way to print the best rated comment?

Laravel Sandbox

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

This is not the most optimal solution, but it should work.

First get the IDs of the Video models from the pagination object:

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

Then use those to join the other tables, grouping by video and picking the highest rating ID. You might need to tweak this if you have other columns on your rating table, i.e. so you can rank them better than using their primary key.

$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();

This will get you a map of the Videos by ID and the highest ranked comment.

This won't get you the names of the rankings however, that can be done in a separate query:

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

Then transform the rating map to include the names:

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

This will give you a collection, keyed by the Video IDs that also contains the rating ID and its name.

A slightly more optimal way to do this is to take the first query and wrap the whole thing into a subquery, that way you could join the ratings table on it again and get the name. Would reduce the queries by one at the cost of making the single query more complex.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda