laravel-8eloquent-relationshipjsonresponse

How to returning only as string column in json response object from eloquent relationship using eager loading


I'm trying to figure out how to eager load data as a string instead of array object from a related table.

I have 3 models and here are the relations

Product.php

class Product extends Model
    {
         public function ProductTag()
        {
            return $this->hasMany(ProductTag::class);
        }
        public function Category()
        {
            return $this->belongsTo(Category::class);
        }
    }

ProductTag.php

class ProductTag extends Model
    {
        public function Product()
        {
            return $this->belongsTo(Product::class);
        }
    }

Category.php

class Category extends Model
    {
        public function Product()
        {
            return $this->hasMany(Product::class);
        }
    }

I've tried doing it like so:

public function tag(){
        return $this->hasMany(ProductTag::class)
            ->selectRaw('GROUP_CONCAT(tag) as tag,id')
            ->groupBy('id');
        }


public static function list(){
    $result = Category::with(['Product'=>function($q){
        $q->with(['tag'=>function($q1){
            $q1->first();
        }]);
   }])->get();
}

Here is the reponse:

{
    "data": {
        "categories": [
            {
                "id": 1,
                "category": "test 1",
                "product": [
                    {
                        "id": 46,
                        "name": "test prod 1",
                        "tag": []
                    },
                    {...}
                ]
            },
            {
                "id": 2,
                "category": "test 2",
                "product": [
                    {
                        "id": 45,
                        "name": "test prod 2",
                        "tag": [
                            {
                                "product_tag": "Test1, test12, test123"
                            }
                        ]
                    },
                    {...}
                ]
            },
            {
                "id": 3,
                "category": "test 3",
                "product": []
            }
        ]
    }
}

The Response is as expected except tag array so, instead of an array named "tag" can I get "product_tag" within the "product" array

"product": [
                    {
                        "id": 45,
                        "name": "test prod 2",
                        "tag": [
                            {
                                "product_tag": "Test1, test12, test123"
                            }
                        ]
                    }
            ]
            

Here is what I want it to look like:

"product": [
                    {
                        "id": 45,
                        "name": "test prod 2",
                        "product_tag": "Test1, test12, test123"
                    }
            ]

Is it possible and any smart way of doing this in Laravel using Eloquent?


Solution

  • Simple :)

    Btw, if you can - rename product_tag in response to tag_line or same - it's not right way to take same name for relation and mutator.

    class Product extends Model
        {
             public function getTagLineAttribute()
             {
                 //tag - is "name" field in ProductTag
                 return $this->ProductTag->pluck('tag')->implode(',');
             }
             public function ProductTag()
            {
                return $this->hasMany(ProductTag::class);
            }
            public function Category()
            {
                return $this->belongsTo(Category::class);
            }
        }
    
    //eager loading with tags
    Product::with('ProductTag')->find(..)->tagLine;