Laravel Eloquent Suma de la columna de la relación

111

He estado trabajando en una aplicación de carrito de compras y ahora he llegado al siguiente problema.

Hay un objeto Usuario, Producto y Carrito.
- La tabla Carrito solo contiene las siguientes columnas: "id", "user_id", "product_id" y marcas de tiempo.
- El UserModel "hasMany" Carts (porque un usuario puede almacenar varios productos).
- El CartModel "pertenece a" un usuario y CartModel "tiene muchos" productos.

Ahora para calcular el total de productos que sólo puede llamar a: Auth::user()->cart()->count().

Mi pregunta es: ¿Cómo puedo obtener la SUMA () de los precios (una columna de producto) de los productos en el carrito de este Usuario?
Me gustaría lograr esto con Eloquent y no usando una consulta (principalmente porque creo que es mucho más limpio).

el almirante
fuente

Respuestas:

220
Auth::user()->products->sum('price');

La documentación es un poco ligera para algunos de los Collectionmétodos, pero todos los agregados del generador de consultas aparentemente están disponibles, además de avg()que se pueden encontrar en http://laravel.com/docs/queries#aggregates .

user1669496
fuente
wow gracias por esa rápida respuesta. Ahora solo dice que no hay una columna de precios. Parece que elocuente no está mirando esa tabla de productos en absoluto ...
Almirante
3
En realidad eso tiene sentido, tienes que agregar la tabla de productos a la relación, lo siento. Pruebe $sum = Auth::user()->cart()->products()->sum('price');o cualquiera que sea la columna de precios en su tabla de productos.
user1669496
1
¡Eso funcionó para mí! Dejé de usar las clases de carro. Tanto el usuario como el producto ahora tienen un método paymentsToMany (). Ahora puedo usar el precio: {{Auth :: usuario () -> productos-> suma ('precio')}} Gracias, este caso está resuelto.
Almirante
9
Algo no está bien aquí: su enlace se refiere a la aplicación de funciones agregadas a las consultas de la base de datos, pero products->sumimplica que es una suma de llamadas en un objeto de colección, en lugar de en el objeto de construcción devuelto por productos (). Vale la pena aclarar a cuál te refieres aquí, e idealmente proporcionar un enlace para explicar ambos.
Benubird
1
@ user3253002 usando una relación sin paréntesis ...->products->...consultará la base de datos para obtener todos los productos relacionados del modelo actual y luego trabajará con esa colección en memoria. Usar ...->products()->...solo modifica la consulta que se está construyendo sin ejecutarla hasta que ->sum()se llame a algo similar. Este último puede ser más eficiente, ya que evita transferir información innecesaria de la base de datos a la memoria.
Siegen
62

esta no es su respuesta, pero es para aquellos que vienen aquí buscando una solución para otro problema. Quería obtener la suma de una columna de la tabla relacionada condicionalmente. En mi base de datos, Deals tiene muchas actividades. Quería obtener la suma de "amount_total" de la tabla de actividades donde activities.deal_id = deal.id y activities.status = pagado, así que hice esto.

$query->withCount([
'activity AS paid_sum' => function ($query) {
            $query->select(DB::raw("SUM(amount_total) as paidsum"))->where('status', 'paid');
        }
    ]);

vuelve

"paid_sum_count" => "320.00"

en el atributo Ofertas.

Esta es ahora la suma que quería obtener, no la cuenta.

ahmad ali
fuente
4
Este es el mejor en muchos casos porque puede ordenar sin tener que obtener todos los registros.
Sabrina Leggett
15

Intenté hacer algo similar, lo que me llevó mucho tiempo antes de poder descubrir la función de recopilación (). Entonces puedes tener algo de esta manera:

collect($items)->sum('amount');

Esto le dará la suma total de todos los elementos.

Abdur Rahman Turawa
fuente
4
el nombre de la función es en realidadcollect()
Leonardo Beal
probablemente sea mejor simplemente hacer un bucle en la matriz. collect()se usa para enriquecer una matriz en un objeto de colección, pero si no tiene una colección en primer lugar, podría ser mejor usar la matriz sin procesar
Flame
0

También usando el generador de consultas

DB::table("rates")->get()->sum("rate_value")

Para obtener la suma de todos los valores de las tarifas dentro de las tarifas de la tabla.

Obtener la suma de los productos de los usuarios.

DB::table("users")->get()->sum("products")
Ahmed Mahmoud
fuente