Laravel Eloquent Sum of Relation's Colonne

111

J'ai travaillé sur une application de panier d'achat et j'arrive maintenant au problème suivant.

Il y a un objet Utilisateur, Produit et Panier.
- La table Cart contient uniquement les colonnes suivantes: "id", "user_id", "product_id" et horodatages.
- Le UserModel "hasMany" Carts (car un utilisateur peut stocker plusieurs produits).
- Le CartModel "appartient à" un utilisateur et CartModel "hasMany" Produits.

Maintenant , pour le calcul total des produits que je peux appeler: Auth::user()->cart()->count().

Ma question est: Comment puis-je obtenir la SOMME () des prix (une colonne de produit) des produits dans le panier par cet utilisateur?
Je voudrais accomplir cela avec Eloquent et non en utilisant une requête (principalement parce que je pense que c'est beaucoup plus propre).

l'amiral
la source

Réponses:

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

La documentation est un peu légère pour certaines Collectionméthodes, mais tous les agrégats du générateur de requêtes sont apparemment disponibles en plus de ceux avg()qui peuvent être trouvés à http://laravel.com/docs/queries#aggregates .

user1669496
la source
wow merci pour cette réponse rapide. Il dit maintenant simplement qu'il n'y a pas de colonne de prix. Il semble éloquent de ne pas regarder du tout cette table de produits ....
theAdmiral
3
En fait, cela a du sens, vous devez ajouter la table des produits à la relation, désolé. Essayez $sum = Auth::user()->cart()->products()->sum('price');ou quelle que soit la colonne de prix sur votre table de produits.
user1669496
1
Cela a fonctionné pour moi! J'ai arrêté d'utiliser les cartclasses. L'Utilisateur et le produit ont maintenant une méthode AppartToMany (). Maintenant, je peux utiliser le prix: {{Auth :: user () -> products-> sum ('price')}} Merci, ce cas est résolu.
theAdmiral
9
Quelque chose ne va pas ici - votre lien fait référence à l'application de fonctions d'agrégation aux requêtes de base de données, mais products->sumimplique qu'il s'agit d'un appel sum sur un objet de collection, plutôt que sur l'objet de générateur renvoyé par products (). Cela vaut la peine de clarifier celui que vous voulez dire ici et, idéalement, de fournir un lien pour expliquer les deux.
Benubird
1
@ user3253002 en utilisant une relation sans parenthèses ...->products->...interrogera la base de données pour obtenir tous les produits associés du modèle actuel, puis travaillera avec cette collection en mémoire. Utiliser ...->products()->...simplement modifie la requête en cours de construction sans l'exécuter jusqu'à ce que quelque chose comme ->sum()soit appelé. Ce dernier peut être plus efficace, car il évite de transférer des informations inutiles de la base de données en mémoire.
Siegen
62

ce n'est pas votre réponse mais c'est pour ceux qui viennent ici chercher une solution à un autre problème. Je voulais obtenir la somme d'une colonne de table liée conditionnellement. Dans ma base de données, Deals a de nombreuses activités, je voulais obtenir la somme du "montant_total" de la table des activités où activités.deal_id = deal.id et activités.status = payé donc je l'ai fait.

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

il retourne

"paid_sum_count" => "320.00"

dans l'attribut Deals.

C'est maintenant la somme que je voulais obtenir pas le décompte.

ahmad ali
la source
4
C'est le meilleur dans de nombreux cas car vous pouvez trier par lui sans avoir à obtenir tous les enregistrements.
Sabrina Leggett
15

J'ai essayé de faire quelque chose de similaire, ce qui m'a pris beaucoup de temps avant de pouvoir comprendre la fonction collect (). Vous pouvez donc avoir quelque chose de cette façon:

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

Cela vous donnera la somme totale de tous les éléments.

Abdur Rahman Turawa
la source
4
le nom de la fonction est en faitcollect()
Leonardo Beal
vous feriez probablement mieux de simplement boucler le tableau. collect()est utilisé pour enrichir un tableau en un objet de collection, mais si vous n'avez pas de collection en premier lieu, il serait peut-être préférable d'utiliser simplement le tableau brut
Flame
0

Utilisation également du générateur de requêtes

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

Pour obtenir la somme de toutes les valeurs de taux dans les taux de table.

Pour obtenir la somme des produits des utilisateurs.

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