laravel filter collection based on relation

Viewed 1253

Assuming the following code to represent an order and the related transactions:

order

public function transactions(){

    return $this->hasMany('App\Transaction');
}

already loaded collection ($orders)

order1
    id
    amount
    transactions (relation)
        txid
        method
        amount

order2
    id
    amount
    transactions (relation)
        txid
        method
        amount

The following filtering on already loaded collection does not work as expected:

                    $isNotEmpty = $orders->filter(function ($order) use ($receivingPayment) {
            return $order->transactions->txid === $receivingPayment->txid && $order->transactions->method === $receivingPayment->method;
          })->isNotEmpty();

It seems like the filtering on the relation transactions doesn't work this way? It returns an empty element even if the transaction id is in the collection.

3 Answers

If you can't or don't want to use the answers above and keep working with the collection you've got, use a combination of filter and pluck:

$orders->filter(function ($order) use ($receivingPayment) {
    return $order->transactions
        ->pluck('id')
        ->containsStrict($receivingPayment->txid);
})

To filter for multiple conditions matching a single transaction, use a combination of multiple where's and isNotEmpty():

$orders->filter(function ($order) use ($receivingPayment) {
    return $order->transactions
        ->where('txid', $receivingPayment->txid)
        ->where('method', $receivingPayment->method)
        ->isNotEmpty();
})

Instead of filtering orders, you wanted to filter transactions. You can do that like this:

$orders->transactions()->where('transactions.txid', '=', $receivingPayment->txid)->get();

You should try whereHas instead.

$orders->whereHas('transactions', function($query) use ($receivingPayment) { $query->where('txid', '=' $receivingPayment->txid})->count();

If there is nothing found, than you should doubleCheck if there no missmatch with $receivingPayment id in database.

Related