Use the laravel diff in two collections

1

I'm trying to fetch items that are not in a particular product.

I have, therefore, a model Produto , each product has several items, and another model Item .

I'm trying to use Laravel's collections , more specifically the diff method, as follows:

public function buscarItens($id)
{
    $produto = Produto::find($id);

    //busca todos os itens cadastrados
    $todosItens = Item::all();

    //busca os itens do produto
    $itensDoProduto = $produto->itens;

    //retorna os produtos que NÃO PERTENCEM ao item + os produtos que PERTENCEM ao item
    $collection1 = collect($todosItens);
    $diff = $collection1->diff($itensDoProduto);

    return response()->json($collection1);
}

It turns out that this difference that is returning is equal to $todosItens itself, as if there were no items in common between $itensDoProduto and $todosItens , but it exists.

What could be happening?

    

asked by anonymous 11.12.2017 / 01:56

1 answer

1

What is the Collection right?

You need to understand that there is a difference between the Illuminate\Database\Eloquent\Collection and Illuminate\Support\Collection classes. The first is returned when you call get in a query made by Eloquent , the second, when you call the collect function.

% w /% of these two classes work in different ways!

Notice the difference between setting the Illuminate \ Database \ Eloquent \ Collection and Illuminate \ Support \ Collection .

So you should choose to use diff of Collection and not Eloquent .

So:

public function buscarItens($id)
{
    $produto = Produto::find($id);

    $todosItens = Item::all();

    $diff = $todosItens->diff($produto->itens);

    return response()->json($diff);
}

Note : I have cleaned up the settings, since it is not necessary to exit by declaring so many variables that are barely used.

Pay attention to the code!

Another detail is that you want to return the difference, but it is returning the variable Support , which represents "all items". This is looking like a flaw in your code writing.

Why not return directly from the query?

You can return relationship-based results through $collection1 queries. There are four methods I usually use for this: Eloquent , whereHas , has , doesntHave .

For example, if I want to return all items that do not have relationships with whereDoesntHave of id Produto , I can use 1 .

$itensNaoRelacionados = Item::whereDoesntHave('produto', function ($query) use ($id) {
                                $query->where('id', '=', $id);
                            })->get();
    
11.12.2017 / 12:00