Laravel Eloquent Soma da coluna da relação


111

Tenho trabalhado em um aplicativo de carrinho de compras e agora cheguei ao seguinte problema.

Há um usuário, um produto e um objeto de carrinho.
- A tabela Carrinho contém apenas as seguintes colunas: "id", "user_id", "product_id" e carimbos de data / hora.
- Os carrinhos "hasMany" do UserModel (porque um usuário pode armazenar vários produtos).
- O CartModel "pertence a" um usuário e os produtos CartModel "hasMany".

Agora, para calcular o total de produtos posso apenas ligar no: Auth::user()->cart()->count().

Minha pergunta é: Como posso obter a SOMA () dos preços (uma coluna de produto) dos produtos no carrinho por este usuário?
Eu gostaria de fazer isso com o Eloquent e não usando uma consulta (principalmente porque acredito que é muito mais limpo).

Respostas:


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

A documentação é um pouco leve para alguns dos Collectionmétodos, mas todos os agregados do construtor de consultas estão aparentemente disponíveis, além dos avg()que podem ser encontrados em http://laravel.com/docs/queries#aggregates .


uau, obrigado por essa resposta rápida. Agora diz apenas que não há coluna de preço. Parece que o eloquent não está olhando para aquela tabela de produtos ....
almirante de

3
Na verdade faz sentido, você tem que adicionar a tabela de produtos ao relacionamento, desculpe. Experimente $sum = Auth::user()->cart()->products()->sum('price');ou qualquer que seja a coluna de preços na tabela de produtos.
user1669496

1
Isso funcionou para mim! Parei de usar as cartclasses. Tanto o usuário quanto o produto agora têm um método belongsToMany (). Agora posso usar o preço: {{Auth :: user () -> produtos-> soma ('preço')}} Obrigado, este caso está resolvido.
theAdmiral

9
Algo não está certo aqui - seu link se refere à aplicação de funções agregadas a consultas de banco de dados, mas products->sumimplica que é a soma de chamadas em um objeto de coleção, em vez de no objeto construtor retornado por produtos (). Vale a pena esclarecer a qual você se refere aqui e, de preferência, fornecer um link para explicar os dois.
Benubird

1
@ user3253002 usando um relacionamento sem parênteses ...->products->...consultará o banco de dados para obter todos os produtos relacionados do modelo atual e, em seguida, trabalhará com essa coleção na memória. Usar ...->products()->...apenas modifica a consulta que está sendo construída sem executá-la até que algo semelhante ->sum()seja chamado. Este último pode ser mais eficiente, pois evita a transferência de informações desnecessárias do banco de dados para a memória.
Siegen

62

esta não é a sua resposta mas é para quem vem aqui em busca de solução para outro problema. Eu queria obter a soma de uma coluna da tabela relacionada condicionalmente. Em meu banco de dados, Deals has many Activities, eu queria obter a soma de "amount_total" da tabela Activities onde Activities.deal_id = deal.id e Activities.status = paid então fiz isso.

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

retorna

"paid_sum_count" => "320.00"

no atributo Ofertas.

Essa é agora a soma que eu queria não contar.


3
Em muitos casos, isso é o melhor porque você pode classificar por ele sem precisar obter todos os registros.
Sabrina Leggett

15

Tentei fazer algo semelhante, o que me levou muito tempo antes de descobrir a função collect (). Então você pode ter algo assim:

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

Isso lhe dará a soma total de todos os itens.


4
o nome da função é na verdadecollect()
Leonardo Beal

você provavelmente está melhor apenas fazendo o loop do array. collect()é usado para enriquecer uma matriz em um objeto de coleção, mas se você não tiver uma coleção em primeiro lugar, pode ser melhor usar apenas a matriz bruta
Flame

0

Também usando o construtor de consulta

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

Para obter a soma de todo o valor da taxa dentro das taxas da tabela.

Para obter o somatório dos produtos do usuário.

DB::table("users")->get()->sum("products")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.