I have many products in my categories and I can get all of the products based on the category successfully. But, when I tried to get the trashed Categories (I used soft delete both in the categories and products), it gave me an error
Call to a member function products() on null
I’ve tried to use a different function name, but the error still occurs.
Models
// CategoryModel
public function products()
{
return $this->hasMany(Product::class, 'category_id','id');
}
// ProductModel
public function category()
{
return $this->belongsTo(Categories::class, 'category_id','id')->withTrashed();
}
Controllers
// IndexController
public function productByCategory($name)
{
$categories = Categories::where('name', $name)->first();
$productsCategories = $categories->products()->get(); // the error occurs here
return view('products-category', compact('productsCategories','categories'));
}
// CategoryController
public function trash()
{
$categories = Categories::onlyTrashed()->paginate(10);
return view("categories.trash", compact('categories'));
}
// ProductController
public function trash()
{
$products = Product::onlyTrashed()->paginate(10);
return view("products.trash", compact('products'));
}
2
Answers
When querying the categories in
productByCategory
, include the trashed items as well. I assume that when deleting a category, you don’t remove its associations with the products.Of course, more logic can be added, but for now, the issue is caused by the trashed categories that are associated with the products. It is not mandatory to handle deleted categories, but the
null
check would be important for error handling.Always remember that a query may not necessarily return any results. Such cases should always be handled.
(Also, I was very confused by the incorrect use of naming conventions: for example, instead of using the singular form "category", you kept using the plural, which made the entire answer confusing at first. I have corrected these in my own response.)
Update
Based on the description in the comment, there should be a different return for trashed and non-trashed categories.
You’re having this error because in your
productByCategory
method, you’re trying to access the products relationship of acategory
, but theCategories::where('name', $name)->first()
call may return null if there is no category with that name found.To properly handle soft-deleted
categories
and avoid this error, you need to include soft-deleted records in your query using thewithTrashed
method when fetching thecategory
. Here’s the updated method below:Also, you’ll need to update your models, to ensure soft-deleted relationship works properly.
For the
category
model, add withTrashed to theproducts
relationship to include soft-deleted products when retrieving categories.for the
product
model, the category relationship already useswithTrashed()
forcategories
, so it should work fine as it is