17

Following this post How to create multiple where clause query using Laravel Eloquent?

I am trying to insert multiple 'and' conditions:

$matchThese = ['destination.country' => 'china', 'doc.description' => 'business'];

    return $collection->where($matchThese);

but I receive this error:

Too few arguments to function Illuminate\Support\Collection::where(), 1 passed . . . but two expected
Stefano Maglione
  • 3,946
  • 11
  • 49
  • 96
  • where expects two parameters, you could probably do something like this return $collection->where($matchThese[0], $matchThese[1]); – utdev Jun 01 '17 at 12:48

4 Answers4

33

Collection where method doesn't accept an array of conditions like eloquent does. But you can chain multiple where conditions.

return $collection->where('destination.country', 'china')
    ->where('doc.description', 'business');

Example

$data = [
    ['name' => 'john', 'email' => 'john@gmail.com'],
    ['name' => 'john', 'email' => 'jim@gmail.com'],
    ['name' => 'kary', 'email' => 'kary@gmail.com'],
];

$collection = collect($data);

$result = $collection->where('name', 'john');
// [{"name":"john","email":"john@gmail.com"},{"name":"john","email":"jim@gmail.com"}]


$result = $collection->where('name', 'john')->where('email', 'john@gmail.com');
// [{"name":"john","email":"john@gmail.com"}]
Sandeesh
  • 11,486
  • 3
  • 31
  • 42
9

Chaining multiple wheres will surely work, but you will do a loop for each one of them. Use filter instead. That will loop through and check for all your conditions only once.

$matchThese = ['destination.country' => 'china', 'doc.description' => 'business'];

return $collection->filter(function ($item) use ($matchThese) {
    foreach ($matchThese as $key => $value) {
        if ($item[$key] !== $value) {
            return false;
        }
    }
    return true;
});
0

Since where expects or needs more then one parameter, it does not work.

That is what your error says:

Too few arguments to function where(), 1 passed . . . but two expected

You could probably do something like this:

return $collection->where($matchThese[0], $matchThese[1]);

Or this

return $collection->where($matchThese[0], OPERATOR, $matchThese[1]); // OPERATOR could be `=` or `<>`

So to have multiple where conditions one can do something like this:

return $collection->where($matchThese[0], $matchThese[1])
                  ->where($foo, $bar);

you can basically just chain them.

utdev
  • 3,942
  • 8
  • 40
  • 70
0

Here's my solution to this issue:

    $matchThese = ['country' => 'china', 'description' => 'business'];
    $data = collect([...]);
    $query = null;

    foreach ($matchThese as $col => $value) {
        $query = ($query ?? $data)->where($col, $value);
    }

At the end of the loop, $query will contain the results.

phoenix
  • 1,629
  • 20
  • 11