Как исправить "нумерация страниц Laravel НЕ обновляется при поиске" - PullRequest
0 голосов
/ 17 октября 2019

Я составляю таблицу заказов, в которой есть определенный текущий шаг, в данном случае это шаг NESTEN и некоторые другие операторы where, чтобы вернуть заказы, которые мне нужны.

Поскольку мне не нужен список с более чем 400 заказами на 1 странице, я хочу использовать функцию разбиения на страницы laravels, которая также повышает производительность в списке из более чем 100 000 записей. Пагинация Laravel работает, как и должно, но проблема возникает, когда я хочу использовать фильтр, который я сделал.

Я сделал выпадающий список, который нужно отфильтровать на основе материала заказов, которые есть в списке. В таблице я вижу отфильтрованные заказы, но нумерация страниц имеет то же количество страниц и количество заказов, что и раньше. Итак, проблема в том, что после фильтрации коллекции по запросу нумерация страниц не обновляется.

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

Также добавлена ​​функция фильтра $ orders-> filter для удаления заказов, которые не соответствуют требованиям фильтра, но без результата ...

Чтобы это было понятно сейчас, ядобавил код в файл Route.

Мой маршрут выглядит следующим образом

Route::get('orders/nesten', function(Request $request) {
    $orders = ShopOrder::where([
        ['ItemCode', 'LIKE', 'CM%'],
        ['Exact', '=', null],
        ['Nesting', '=', null],
        ['IsOnHold', '!=', 1],
        ['ShopOrderRoutingStepPlanCount', '!=', 0]
    ])->paginate(50);

    $filteredCollection = $orders->filter(function ($order) use($request) {
        if($request->exists('material')) {
            return $order->getCurrentStep() == 'Nesten' 
                   && $order->getMaterial() == $request->get('material');
        }
        return $order->getCurrentStep() == 'Nesten';
    });

    $orders->setCollection($filteredCollection);
    return view('dashboard/actions/Nesten')->with('shopOrders', $orders);
});

В модели ShopOrder я объявил функции -> getMaterial () и -> getCurrentStep () как

    public function routingStepPlans() {
        return $this->hasMany('App\Models\Exact\ShopOrder\RoutingStepPlan', 'ShopOrder', 'ID');
    }

    public function materialPlans() {
        return $this->hasMany('App\Models\Exact\ShopOrder\MaterialPlan', 'ShopOrder', 'ID');
    }

    public function getCurrentStep() {
        $current = $this->routingStepPlans()->where('LineNumber', ($this->timeTransactions()->count() + 1))->first();

        if(isset($current->Description)) {
            return $current->Description;
        }

        return 'Afgerond';
    }

    public function getMaterial() {
        $material = $this->materialPlans()->where('ItemCode', 'LIKE', 'TAP%')->first();

        if(isset($material->Description)) {
            return $material->Description;
        }
        return '-';
    }

и как последний вид

        <table class="table table-striped table-bordered no-width">
            <thead>
                <tr>
                    <th>Order nummer</th>
                    <th>SKU</th>
                    <th>Omschrijving</th>
                    <th>Aantal</th>
                    <th>Datum</th>
                    <th>Deadline</th>
                    <th>Materiaal</th>
                    <th>DXF?</th>
                </tr>
            </thead>
            <tbody>
                @foreach($shopOrders as $shopOrder)
                    <tr>
                        <td>{{ $shopOrder->ShopOrderNumber }}</td>
                        <td>{{ $shopOrder->ItemCode }}</td>
                        <td>{{ str_replace('Car Mats', '',$shopOrder->Description) }}</td>
                        <td>{{ $shopOrder->PlannedQuantity }}</td>
                        <td>{{ $shopOrder->PlannedStartDate }} </td>
                        <td>{{ $shopOrder->PlannedDate }}</td>
                        <td>{{ $shopOrder->getMaterial() }}</td>
                        <td>{{ $shopOrder->hasDxf() }}</td>
                    </tr>
                @endforeach
            </tbody>
        </table>
        {{ $shopOrders->total() }}
        {{ $shopOrders->appends(['material' => Request::get('material')])->render() }} 

Я ожидаю, что 1 страница будет разбита на страницы с заказами / nesten? Материал = Саксония% 20Zwart & page = 1 как URL, так как у этого материала 9 заказов.

Но в настоящее время он по-прежнему имеет 151 страницу, так же, как просто переходить к заказам / нестен.

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Из того, что я вижу, вы выбираете все записи из базы данных, а затем фильтруете их с помощью фильтра Коллекции. Разбивка на страницы строится на основе результатов запроса к базе данных, поэтому вам необходимо обновить запрос, чтобы выполнить фильтрацию.


Обновление

  1. Создать класс абстрактного фильтра
namespace App\Http\Filters;

use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;

class AbstractFilter
{
    protected $builder;

    protected $request;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function apply(Builder $builder)
    {
        $this->builder = $builder;

        foreach($this->filters() as $name => $value) {
            if(method_exists($this, $name)) {
                call_user_func_array([$this, $name], array_filter([$value]));
            }
        }

        return $this->builder;
    }

    public function filters()
    {
        return $this->request->all();
    }
}
Расширить этот класс для вашего запроса (ПРИМЕЧАНИЕ. Здесь имена методов являются параметрами запроса для фильтров):
namespace App\Http\Filters;

class OrdersFilter extends AbstractFilter
{
    public function material($value = null)
    {
        if (!is_null($value)) {
            // return modified query here (return $this->builder->where....) 

        }
    }
}

Добавление области действия для вашей модели (в модели ShopOrder):
public function scopeFilter($query, OrderFilters $filter) {
    return $filter->apply($query);
}
Обновите ваш запрос следующим образом:
$orders = ShopOrder::whereLike('ItemCode', 'CM%')
    ->whereNull('Exact')
    ->whereNull('Nesting')
    ->where('IsOnHold', '!=', 1)
    ->where('ShopOrderRoutingStepPlanCount', '!=', 0)
    ->filter(new OrdersFilter($request))
    ->paginate(50);

И вы можете пропустить фильтрацию всей коллекции. Также вы можете добавить дополнительные параметры фильтра в класс OrdersFilter.

ПРИМЕЧАНИЕ: я написал все без тестирования, поэтому могут быть небольшие ошибки. Также я не написал фильтр материалов, не имея структуры базы данных, но ваши методы Model могли бы быть лучше.

UPDATE

для метода фильтрующих материалов, я бы использовал что-то вроде этого (не 100%, если быработает, не проверял):

public function material($value = null) {
    if (!is_null($material)) {
        return $this->builder->having('', function($query) use ($value) {
            return $query->where('ItemCode', 'LIKE', 'TAP%')
                ->where('description', '=', $value);
        })
        ->having('routingStepPlans', function($query) {
            return $query->where('LineNumber', ShopOrder::timeTransactions()->count() + 1)
               ->where('description', '=', 'Nesten');
        });
    }
}
0 голосов
/ 17 октября 2019

, чтобы продолжить нумерацию страниц, но продолжайте поиск

{{ $shopOrders->appends(Request::except('page'))->links() }}
...