Hans M.
Hans M.

Reputation: 79

Laravel: Best way to compare two collections: whereIn?

I have a table with categories, one table with products and another table products_user which tracks the products a user owns.

When displaying products on a page it should change a button from Buy to Bought if a user owns the product.

I get the products to display through $categories->products. What is the most efficient way to find out which of these products a user already owns?

I don't want to load the entire collection of the user owned products into the memory since these could be several thousands. I also don't want to create a Mysql query for each check.

There is an option for a wherein clause. But even then I am that there is a smarter way to create this clause without looping through every product to build an array.

Can someone help me to come up with a good logic? thank you

Upvotes: 0

Views: 2787

Answers (1)

Ben
Ben

Reputation: 5129

You can make use of Constraining Eager Loads to append more information to your products. In this case, the user_id is either NULL or user_id, meaning the user is bought the product or not.

$categories = Category::with(['products' => function ($q) {
    $q->select(['products.*', 'user_id'])
        ->leftJoin('products_user', 'user_products.product_id', '=', 'products.id')
        ->where(function ($q) {
            $q->whereNull('user_id')->orWhere('user_id', Auth::user()->id);
        });
}])->get();

foreach ($categories as $category) {
    $products = $category->products;
    foreach ($products as $product) {
        if (empty($product->user_id)) {
            // user not yet bought the product
        }
        else {
            // user already bought the product
        }
     }
}

Upvotes: 1

Related Questions