Saltar al contenido

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 atributo points aparezca al serializar o convertir a array.

  • getPointsAttribute(): Calculamos la suma de points entre posts y forums.

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í?

  1. withCount en Laravel permite contar los registros relacionados, pero también podemos usar una subconsulta con DB::raw('sum(points)').

  2. Renombramos esas subconsultas a forum_points y post_points.

  3. 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 (withCount o withSum) son más eficientes cuando ordenas o filtras desde la base de datos, evitando N+1 queries.

  • Atributos Modernos con Attribute se 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!

school Curso completo

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.

access_time 8 horas de contenido
layers 4 tecnologías en 1
update 100% actualizado
code Proyectos prácticos
Ver Curso Laravel 12 arrow_forward

star Incluido en cualquier suscripción

Rutas de aprendizaje