Вынудить определенный порядок идентификатора массива искать объект в Eloquent - PullRequest
0 голосов
/ 19 июня 2019

Я использую Laravel (и, следовательно, eloquent).

У меня очень сложный поиск по нескольким объединениям в нескольких таблицах в eloquent.Требуется определенный порядок через несколько таблиц / дочерних объединений.Это означает, что использовать ORM-часть laravel нецелесообразно, даже если красноречивый аспект:

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

Laravel имеет следующие методы:

  • $object::find($ids)
  • $object::whereIn('id', $ids)->get()

По сути, эти ответы идентичны, если они выполняются со следующими массивами:

  • [1,2,3]
  • [3,2,1]

т.е. они отвечаюткак будто заказано по ID.

Как я могу форсировать определенный порядок, который я передаю ему?

Я знаю, что это можно сделать в MySQL:

  • select * from records where id in (3,4,5) order by field(id,4,5,3)

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 19 июня 2019

Это не проверено, однако, создав область запроса , чтобы выполнить все, что задумано, вы сможете выполнить это.

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

Область запроса может принимать несколько аргументов (исключая обязательный аргумент $query): $field & $values. В этом примере вы можете передать поле id и значения, являющиеся массивом идентификаторов.

Затем он выполнит обычный вызов where, получит все результаты, затем создаст новую коллекцию результатов, которые теперь находятся в указанном порядке.

Примечание : возвращая коллекцию, область эмулирует коллекцию, возвращаемую методом ->get().

public function getInOrder($query, $field, $values)
{
    $results = $query->whereIn($field, $values)->get();

    $reorder = collect();

    foreach ($ids as $id) {
        $reorder[] = $results->where($field, $values)->first();
    }

    return $reorder;
}

Вы вызываете эту функцию объема, используя:

$object::getInOrder('id', $ids);

Примечание : так как при этом возвращается коллекция, она больше не использует методы построителя запросов, а только методы коллекции.

0 голосов
/ 21 июня 2019

Это в значительной степени опирается (ну .. почти так же) на ответ, данный @ thisiskelvin

Пожалуйста, подпишите его вместо этого ответа (или обоих)

Я создал черту .. которую я назвал AdvancedModelLookup в app\Traits.

В этом я создал слегка измененную функцию из предоставленного кода:

<?

namespace App\Traits;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;

trait AdvancedModelLookup
{
    /**
     * This run a query and orders the objects as per a provided array/collection.
     *
     * @param $query Builder
     * @param $field
     * @param $ids Collection|array
     *
     * @return Collection
     */
    public static function getInOrder(Builder $query, string $field, $ids): Collection
    {
        $results = $query->whereIn($field, $ids)->get();

        $reorder = collect([]);
        foreach ($ids as $id) {
            $reorder->push($results->where($field, $id)->first());
        }

        return $reorder;
    }}

Теперь используйте эту черту:

use App\Traits\AdvancedModelLookup;

class SomeObject extends Model
{

    use AdvancedModelLookup;

    //...

}

Пример использования:

$order = [4,5,3];
$query = SomeObject::whereIn('id', $order);

$normal_lookup = $query->get();
$sorted_lookup = SomeObject::getInOrder($query, 'id', $order);

dd($normal_lookup, $sorted_lookup);

// Normal lookup order: 3,4,5
// Sorted lookup order: 4,5,3

Обратите внимание, вы можете легко расширить или создать дополнительные версии этого стиля функциональности, такие как pluck() и т. Д. *

Эта черта позволяет быстро включить ее для каждой модели без необходимости связываться с наследованием объекта.

0 голосов
/ 19 июня 2019

Вы можете использовать коллекцию результатов для работы с ней:

https://laravel.com/docs/5.8/collections#method-sortby

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...