Получить сумму счета в методе class

Извините за мой английский.

Я хочу сделать запись, которая бы выводила мне сумму всех моих ордеров, то есть складывала строки ордеров и рисовала сгруппированные по ордерам.

Я создал модель «продажа», которая содержит метод AmountOrder

public function AmountOrder()
    {

        $AmountOrder = DB::table('goods')
            ->join('sale_lines', 'sale_lines.good_id', '=', 'goods.id')
            ->where('sale_id', $this->id)
            ->select(DB::raw('SUM(price*quantity) as total_sales'))
            ->value('total_sales');

        return $AmountOrder;

    }

и вывести такой код

@foreach ($sales as $sale)
    <tr>
        <td class="table-text"><div>{{ $sale->id }}</div></td>

        <td>
            {{ $sale->client->name }}
        </td>
        <td>
            {{$sale->date}}
        </td>
        <td>
            {{$sale->AmountOrder($sale)}}
        </td>
        <td>
            {{$sale->debt($sale)}}
        </td>
        <td>
            {{$sale->date_of_issue}}
        </td>
    </tr>
@endforeach

Но проблема в том, что запрос выполняется в каждой строке. Я новичок в Laravel, но подумал, может быть, вы можете решить эту проблему как-то более красиво?

Заранее большое спасибо!

5 ответов

  1. Вы, вероятно, говорите о нетерпеливой нагрузке .

    Из документов:

    При доступе к красноречивым отношениям в качестве свойств данные отношений «лениво загружаются». Это означает, что данные отношения фактически не загружаются до первого доступа к свойству. Тем не менее, Evolvent может «нетерпеливо загружать» отношения во время запроса родительской модели. Активная загрузка устраняет проблему N + 1 запросов.

    Однако вы не сможете использовать Eagle Loading сейчас, с этим кодом в AmountOrderметоде.

    Простой поиск google, также, привел меня к этому примеру нетерпеливой загрузки с агрегатными функциями/отношениями.

    Это, вероятно, будет хорошим началом, чтобы подумать и реализовать свое решение.

  2. вы ошиблись в выборе :

        $AmountOrder = DB::table('goods')
            ->join('sale_lines', 'sale_lines.good_id', '=', 'goods.id')
            ->where('sale_id', $this->id)
            ->select(DB::raw('SUM(sale_lines.price*sale_lines.quantity) as total_sales'))
            ->value('total_sales');
    
  3. Свои взаимоотношения

    class Sale extends Model
    {
        //Получаем товар в этой продаже
        public function good()
        {
            return $this->belongsTo('App\Good');
        }
    }
    
    
    class Good extends Model
    {
        //В каких закупках был этот товар
        public function purchases()
        {
            return $this->hasMany('App\Purchase');
        }
    
        //Продажи с этим товаром
        public function sales()
        {
            return $this->hasMany('App\Sale');
        }
    }
    

    Правильно ли это?

  4. В моей модели я создаю метод

    public function AmountOrderRelation()
    {
    
        return $this->belongsTo('App\Good')
            ->selectRaw('sum(price) as aggregate, id')
            ->groupBy('id');
    }
    

    В контроллерах

    $new_sales = Sale::with('AmountOrderRelation')->get();
    
    
    @foreach ($new_sales as $sale)
                    <tr>
                        <td class="table-text"><div>{{ $sale->id }}</div></td>
    
                        <td>
                            {{ $sale->AmountOrderRelation }}
                        </td>
    
                    </tr>
                @endforeach
    

    Но мои отношения нулевые. В чем моя ошибка?

  5. Я сделал это!

    public function AmountOrder()
    {
    
        return $this->HasOne('App\SaleLines')
            ->join('goods', 'sale_lines.good_id', '=', 'goods.id')
            ->selectRaw(DB::raw('SUM(price*quantity) as aggregate, sale_id'))
            ->groupBy('sale_id');
    }
    
    public function getAmountOrderAttribute()
    {
        // if relation is not loaded already, let's do it first
        if ( ! array_key_exists('AmountOrder', $this->relations))
            $this->load('AmountOrder');
    
        $related = $this->getRelation('AmountOrder');
    
        // then return the count directly
        return ($related) ? (int) $related->aggregate : 0;
    }
    

    И в регуляторе

    $sales = Sale::with('AmountOrder')->get();