Search code examples
laravellaravel-5laravel-collection

Laravel 'where' collection method modifies the collection


Does the Laravel wherecollection method modify the collection?

On the Laravel documentation you can read this:

almost every method returns a new Collection instance, allowing you to preserve the original copy of the collection

And the only methods which have a warning about modifying the collection are transformand forget

But I have this code:

    $descriptions = Description::where('description', $request->description);

    if ($descriptions->count()) {
        $descriptionsWithSameUnit = $descriptions->where('unit_id', $request->unit);
        if ($descriptionsWithSameUnit->count()==0) {
            $descriptionsWithAnotherUnit = $descriptions->where('unit_id', '!=', $request->unit);
            if ($descriptionsWithAnotherUnit->count()) {
        ...

And the collection IS modified after the first where so $descriptionsWithAnotherUnit is always empty, because on that point the collection only has the records where unit_id == $request->unit. Is this a bug in the framework or in the documentation?

And the question that arises from here: What can I do to keep a copy of the original object without retrieving again from the DB? I tried this:

$descriptions = Description::where('description', $request->description);

if ($descriptions->count()) {
    $descriptionsWithSameUnit = $descriptions;
    $descriptionsWithSameUnit->where('unit_id', $request->unit);
    ...

But the $descriptions object is also modified when I apply the where method to the $descriptionsWithSameUnit object


Solution

  • The first thing is that to get collection you need to use get, so if you want to get collection, you should do:

    $descriptions = Description::where('description', $request->description)->get();
    

    and not only:

    $descriptions = Description::where('description', $request->description);
    

    Second thing is that there's no possibility to use operator using where method on collection, so:

    $descriptionsWithAnotherUnit = $descriptions->where('unit_id', '!=', $request->unit);
    

    is completely incorrect. You should use filtermethod here.