laravel / nova-issues

553 stars 34 forks source link

Nova doesn't respect ordering by scout #1836

Closed approached closed 5 years ago

approached commented 5 years ago

Description

Nova doesn't respect ordering by scout. It used instead the last query ordering.

Steps To Reproduce

Just search for something without the order function.

Fixing


<?php

    /**
     * Build an "index" query for the given resource.
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @param  string  $search
     * @param  array  $filters
     * @param  array  $orderings
     * @param  string  $withTrashed
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function buildIndexQuery(NovaRequest $request, $query, $search = null,
                                           array $filters = [], array $orderings = [],
                                           $withTrashed = TrashedStatus::DEFAULT)
    {
        return static::applyOrderings($request, static::applyFilters(
            $request, static::initializeQuery($request, $query, $search, $withTrashed), $filters
        ), $orderings)->tap(function ($query) use ($request) {
            static::indexQuery($request, $query->with(static::$with));
        });
    }

    /**
     * Apply any applicable orderings to the query.
     *
     * @param \Laravel\Nova\Http\Requests\NovaRequest $request
     * @param \Illuminate\Database\Eloquent\Builder   $query
     * @param array                                   $orderings
     * @return \Illuminate\Database\Eloquent\Builder
     */
    protected static function applyOrderings(NovaRequest $request, $query, array $orderings)
    {
        if (!empty($orderings)) {
            foreach ($orderings as $column => $direction) {
                $query->orderBy($column, $direction);
            }

            return $query;
        }

        // if query has search without order, so than we will search results by score
        if ($request->has('search') && !empty($request->get('search'))) {
            return $query;
        }

        // if query has order get parameter, so than we use default from resource
        if (property_exists(static::class, 'orderBy')) {
            foreach (static::$orderBy as $column => $direction) {
                $query->orderBy($column, $direction);
            }

            return $query;
        }

        // use last order
        return empty($query->orders)
            ? $query->latest($query->getModel()->getQualifiedKeyName())
            : $query;
    }
approached commented 5 years ago

Fixing code has a implementation with default order from: #156

davidhemphill commented 5 years ago

Duplicate of #801