0

I'm working on a Laravel project and I want to create a REST API for a website. On my system, I have two tables: my tables are Item and Product table which both have one to one relationship i want the json response from two tables like below

"data": [
        {
            "product_id": 3,
            "product_name": "xyz",
            "sold": 0,
            "total": 500
            }
        }
        ]

but the actual format am getting is like below

"data": [
        {
            "product_id": 3,
            "product_name": "xyz",
            "prod": {
                "id": 1,
                "products_id": 3,
                "sold": 0,
                "total": 500
            }
        }
        ]

My Item Controller class

class ItemCont extends BaseController
{
    
    public function index()
    {
        $items= Items::all();

        return $this->sendResponse(ItemResource::collection($items), 'Items retrieved successfully.');
    }
}

My ItemResource class

     class ItemResource extends JsonResource
{
   
    public function toArray($request)
    {
        
        return parent::toArray($request);

       
    }
}

Items Model

    class Items extends Model
    {
        public $timestamps = false;
        protected $primaryKey = 'product_id';
    
        protected $guarded = [];
        protected $fillable = [
            'product_name'
        ];
    
           
        public function prod(){
            return $this->hasOne('App\Products','products_id','product_id');
        }
    }
products Model
    class Products extends Model
    {
        public $timestamps = false;
        protected $primaryKey = 'id';
    
        protected $guarded = [];
        protected $fillable = [
            'sold','total'
        ];
    
        
        public function item(){
            return $this->belongsTo('App\Items','product_id','products_id');
        }
     
        }
products resource class
class ProductResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
             
       return parent::toArray($request);
      
    }

Thanks The second method i Have tried is my ItemResource class

class ItemResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        
        //return parent::toArray($request);

        return [
            'Product_id' => $this->id,
            'product_name' => $this->name
            //'products' => new Products($this->products),
            //'sold' => $this->sales,
            //'total' => $this->total,
        ];
    } 

my Product Resource class

class ProductResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
               return [
            "sold" => $this->sales,
         "total"=>$this->total
            
       ];
         //   return parent::toArray($request);

      
    }

and my ItemController class

class ItemCont extends BaseController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $items= Items::with('prod')->get();

        return $this->sendResponse(ItemResource::collection($items), 'Items retrieved successfully.');
    }

Response for second method try is

{
    "success": true,
    "data": [
        {
            "Product_id": null,
            "product_name": null
        },
        {
            "Product_id": null,
            "product_name": null
        }
    ],
    "message": "Items retrieved successfully."
}
Khal
  • 219
  • 5
  • 19
  • 1
    one option is to construct json resource manually the way you want. Refer here: https://laravel.com/docs/7.x/eloquent-resources#writing-resources. Another option is to use query builder to build the query manually and select the needed columns. – user3532758 Jul 25 '20 at 14:39
  • It only works for single if write the for both in resources post man will not load values. $items= Items::all(); but for both if i make $items= Items::with(prod)->get() will not work. – Khal Jul 25 '20 at 15:48
  • Can you share your changes to ItemResource class? – user3532758 Jul 25 '20 at 15:51
  • @user3532758 Thanks i have updated my question i have put second method kindly check it all produces null Thanks for help – Khal Jul 25 '20 at 16:09
  • Try this: Get items with prod. Then in resource class, below product_id line, 'sold' => $this->prod->sold, But you need to have a ItemCollection class separately. Check https://laravel.com/docs/7.x/eloquent-resources#resource-collections. Read about resource collection class. If you still have difficulties, I will post an answer for you – user3532758 Jul 25 '20 at 16:11
  • @user3532758 with resource also not loading simple way will help me thanks alot. – Khal Jul 25 '20 at 16:43
  • ok ill post an answer – user3532758 Jul 25 '20 at 17:11

1 Answers1

0

First, you need to manually construct the return array in your ItemsResouce class, like so:

public function toArray($request)
{
  return [
        "product_id" => $this->id,
        "product_name"=> $this->name,
        "sold" => $this->prod->sold,
        "total" => $this->prod->total
        ];
}

Next you need to create a resource collection class, you can name it ItemCollection. You can use php artisan make:resource ItemCollection command to make the class. The class should look like this:

class ItemCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

And in the index method of your controller, you can return the response like so:

//use use App\Http\Resources\ItemCollection;
public function index()
{
    $items= Items::with('prod')->get();
    return new ItemCollection($items); //or use your send response helper method
}
user3532758
  • 2,221
  • 1
  • 12
  • 17