Запрос на Eloquent на основе отношений - PullRequest
1 голос
/ 27 января 2020

У меня есть 2 модели, Transaction, TrackingNumber.

Отношения и поля:

Transaction: hasMany TrackingNumber

Transaction fields: id | carrier
TrackingNumber fields: id | transaction_id

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


a) Если я использую готовую загрузку, он вернет все номера отслеживания независимо от грузоотправителя и вернет только отношение транзакции на основе где:

$collection = TrackingNumber::with(['transaction' => function($q) {
    $q->where('carrier', 'ups')
}])->get();

Так что это не то, что я хочу. Я хочу, чтобы у $collection были только номера отслеживания с указанным оператором.


b) Если я сделаю что-то подобное, я получу результат, но он будет очень неэффективным (так как он выполняет 2 запроса и сохраняет данные в массиве; также, если массив слишком большой, он не работает в whereIn.)

$transactionIds = Transaction::where('carrier', 'ups')->pluck('id');
$trackingNumbers = TrackingNumber::whereIn('id', $transactionIds)->get();

// The result is what I want but it is inefficient.

c) Я также попробовал кое-что как это, но это не волнует, где: /

\DB::table('tracking_numbers')
   ->join('transactions', 'tracking_numbers.transaction_id', '=', 'transactions.id')
   ->where('transactions.carrier', 'ups')
   ->get();

d) я не хочу использовать whereHas(), потому что это очень медленно с большим количеством данных (у меня есть + 1м строк в моих таблицах)


Каков Laravel способ добиться этого?

1 Ответ

1 голос
/ 27 января 2020

Использование гдеHas должно дать вам нужные результаты:

TrackingNumber::whereHas('transaction', function ($query) {
    $query->where('carrier', 'ups');
})->get();

Или попробуйте реструктурировать запрос с c, например:

\DB::table('tracking_numbers')
   ->join('transactions', function ($join) {
        $join->on('tracking_numbers.transaction_id', '=', 'transactions.id')
             ->where('transactions.carrier', 'ups');
   })
   ->get();
...