Reputation: 79
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
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