t0berius's avatar

collection check for existing IDs inside collection

Using this code:

    //fetch all ids
    $editableStockItemIds = $product->stockItems()->available()->select(['id'])->get();

How can I now perform a check if $request->stockItem are part of editableStockItemIds?

dd($editableStockItemIds->contains('id', [$request->stockItem]));

doesn't work as expected, will I need to loop manually through every item inside the collection?

0 likes
19 replies
Nakov's avatar

@t0berius what if you simply try:

// this will return a collection of just IDs
$editableStockItemIds = $product->stockItems()->available()->pluck('id');

// and then
dd($editableStockItemIds->contains($request->stockItem)); 

Assuming that the stockItem from the request is a single ID not an array of IDs.

GeordieJackson's avatar

@t0berius

Would you dump($editableStockItemIds) and post the result so we can see exactly what we're looking at.

Snapey's avatar

so $request->stockItem is an array of Ids from the form?

You want to check if ANY of these are in the available stock items?

OR you want to check that ALL of these are in the available stock items?

OR you want to check that NONE of these are in the available stock items?

One approach is to use the request ids in a whereIn eloquent query. The result you get back will be no records, some records but a different count, or exactly the same count. Use this depending on which of the above questions you want to answer

t0berius's avatar

@snapey I want to make sure that ALL of these are in the available stock items. Some kind of "validation" for the IDs from the form, to make sure they all are part of the product itself (stockItems of the product).

Snapey's avatar

So maybe as suggested. Count the IDs provided, query the database, count the result. If the counts are the same then your query of the database was an accurate match.

GeordieJackson's avatar

Could you not just use:

$editableStockItem = $product->stockItems()->available()->whereId($request->stockItem->id)->first();

To return it if it's available; or

$editableStockItem = $product->stockItems()->available()->whereId($request->stockItem->id)->exists();

to check its availability instead of getting a list of Ids and looping through them?

t0berius's avatar

@snapey

I've used:

    //make sure all IDs from POST request are part of the stockItems which are available for the selected product
    abort_unless(collect($request->stockItem)->keys()->diff($editableStockItemIds)->isEmpty(), 404);

any thoughts against?

GeordieJackson's avatar

What is it you're trying to do?

Are you just checking whether the $request->stockItem is available by checking whether its Id is in the list of available products, or something else?

t0berius's avatar

@geordiejackson I'm checking if the posted ids from form (array) are all in a collection (editableStockItemIds). This is a check to make sure, the ids of the items a user is trying to edit are somehow "related" to the users products.

GeordieJackson's avatar

I would suggest renaming $request->stockItem to $request->stockItems - that's good programming practice.

Your idea of:

abort_unless(collect($request->stockItem)->keys()->diff($editableStockItemIds)->isEmpty(), 404);

Should work.

jlrdw's avatar

Turn $request->stockItem into a collection, do a loop, and each Loop see if it's part of $editableStockItemIds. I imagine using in.

Edit: Not in, but contains, I was thing sql at first -- sorry.

t0berius's avatar

Any problems with my approach (turning the request POST form into a collection and compare both collections using diff())?

Snapey's avatar

not if implemented properly, but since you are doing a query anyway....

davidifranco's avatar

Hey, just my thoughts... maybe this quick one liner?

$editableStockItem = StockItems::with('product')->available()->where('product_id', $product->id)-> findOrFail($request->stockItem);

Just make sure to use findOrFail at the very end of your query.

Please or to participate in this conversation.