SimplyBoose's avatar

Get one relation from MorphToMany using withWhereHas

Hello, Is it possible to get one Model relation if it already uses MorphToMany relation..

I have products and category models where Category model has MorphToMany relation to product. In my app I have specific need to get Image from product to category, through product (I use Spatie/MediaLibrary package for saving product images), but I need to retrieve only first product that has image.

0 likes
1 reply
LaryAI's avatar
Level 58

Yes, it is possible to get one Model relation if it already uses MorphToMany relation. You can use the with method to eager load the product relation with the image constraint. Then, you can use the first method to retrieve only the first product that has an image.

Here's an example code snippet:

$category = Category::with(['products' => function ($query) {
    $query->whereHas('media', function ($query) {
        $query->where('collection_name', 'images');
    })->with(['media' => function ($query) {
        $query->where('collection_name', 'images')->orderBy('order_column');
    }]);
}])->find($categoryId);

$firstProductWithImage = $category->products->first();
$image = $firstProductWithImage->getFirstMedia('images');

In this example, we first eager load the products relation with a constraint that checks if the product has an image in the images collection. Then, we use the with method again to eager load the media relation with the same constraint and an additional orderBy clause to get the first image. Finally, we retrieve the first product with an image using the first method and get the first image using the getFirstMedia method.

Note: This solution assumes that you have set up the Spatie/MediaLibrary package correctly and have added the HasMedia trait to your Product model.

Please or to participate in this conversation.