En ocasiones, necesitas ordenar tus modelos en base a la suma de ciertos valores en relaciones distintas. Por ejemplo, un usuario puede tener puntos acumulados tanto en sus foros como en sus posts. A continuación, veremos cómo lograrlo usando Eloquent de una forma limpia y optimizada.
1. Definir la Relación y el Atributo Calculado
1.1. El Modelo User
En el siguiente ejemplo, cada usuario (User) tiene muchas publicaciones (Post) y muchos foros (Forum). Queremos calcular la cantidad total de puntos que ha obtenido sumando los puntos de todas sus publicaciones y foros.
Usando el Mecanismo Clásico (getPointsAttribute)
Puntos clave:
protected $appends = ['points']: Forzamos a que el atributopointsaparezca al serializar o convertir a array.getPointsAttribute(): Calculamos la suma depointsentrepostsyforums.
1.2. Usando Atributos Modernos con Casts\Attribute
A partir de Laravel 8.42 se recomienda usar la clase Attribute. Quedaría así:
Ventajas:
Sintaxis más clara y organizada.
Mantiene la filosofía de getters/setters “nuevos” en Laravel.
2. Consultar y Ordenar Usando Sumatorios
Para ordenar a los usuarios según sus puntos de posts y forums, usaremos la función de Eloquent. Hay dos enfoques principales:
2.1. Usar withCount con DB::raw
¿Qué sucede aquí?
withCount en Laravel permite contar los registros relacionados, pero también podemos usar una subconsulta con
DB::raw('sum(points)').Renombramos esas subconsultas a
forum_pointsypost_points.Luego ordenamos usando
orderByRaw('forum_points + post_points DESC').
2.2. Usar withSum (si tu versión de Laravel lo permite)
A partir de Laravel 8.x se incluyó withSum, que hace más explícito lo que queremos:
De esta forma, Laravel generará subconsultas que calculen la suma de points para cada relación.
Nota: Al terminar, cada User tendrá las propiedades forum_points y post_points disponibles.
3. Comparación y Recomendaciones
Atributo en el Modelo (
points) es ideal para mostrar la información en tus vistas (o en tu API).Subconsultas (
withCountowithSum) son más eficientes cuando ordenas o filtras desde la base de datos, evitando N+1 queries.Atributos Modernos con
Attributese ajustan a las recomendaciones recientes de Laravel, haciendo el código más limpio y mantenible.
4. Conclusión
Combinar subconsultas (withSum o withCount + DB::raw) con un atributo calculado en el modelo te permite mostrar y ordenar los datos de la forma más óptima. Así, no solo ofreces datos actualizados y centralizados en el modelo, sino que también evitas múltiples consultas innecesarias.
¿Ya has implementado sumatorios en tus relaciones para ordenar tus resultados? ¡Comparte tu experiencia con tus colegas y no olvides explorar la Ruta de Aprendizaje Laravel 11!
Curso Laravel 12
Completo 2026
El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.
star Incluido en cualquier suscripción