@akvaskov Sorry, the answer is a bit big, but it's critical to understand!
TL;DR
- Your
lastOrders()method is correct. - To retrieve data from
lastOrders(), you must use$product->lastOrders()->get()to get the filtered results because you appliedwhere.
It's funny though, but it's important to understand. Let's walk through a clear solution to your issue.
You have a custom relationship method lastOrders() that applies a where clause to filter orders made in the last 3 days. You want to retrieve those filtered orders from the Product model.
⚠️ Here’s the key point: When you create a custom relationship like lastOrders(), you're still returning a query builder, which requires methods like get(), first(), etc., to execute and retrieve the actual data.
public function lastOrders(): HasMany
{
return $this->hasMany(Order::class, 'product_id', 'id')
->where('date', '>', Carbon::today()->subDays(3));
}
This method returns a HasMany relationship with a where condition. The important part is how you call this method.
How to retrieve data using lastOrders()
To actually retrieve the data from the lastOrders() relationship, you need to execute the query by calling methods like get(), or first(), or by eager loading.
For example,
$product = Product::find(1); // Assuming you're looking for Product ID 1
$lastOrders = $product->lastOrders()->get(); // This executes the query and retrieves the filtered orders
// Now, $lastOrders will contain all orders from the last 3 days.
// Or with eager loaing
$products = Product::with('lastOrders')->get();
// Each product will have a 'lastOrders' property with the related orders from the last 3 days
Why using orders() works, but lastOrders() returns null
When you call $product->orders, Laravel automatically returns the related orders without needing additional query execution (like get()). However, when you add a where clause in lastOrders(), you're modifying the relationship and returning a query builder. You need to explicitly tell Laravel to execute that query by calling methods like get() or first().