как форматировать ответы JSON с Relationship - Laravel/Eloquent

Я работаю над проектом Laravel и хочу создать REST API для веб-сайта. В моей системе у меня есть две таблицы: мои таблицы - это таблица Item и Product, которые имеют отношение один к одному. Я хочу получить ответ json из двух таблиц, как показано ниже.

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

но фактический формат, который я получаю, как показано ниже

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

Мой класс контроллера элементов

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

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

Мой класс ItemResource

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

       
    }
}

Модель предметов

    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);
      
    }

Спасибо. Второй метод, который я пробовал, - это мой класс ItemResource.

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,
        ];
    } 

мой класс ресурса продукта

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);

      
    }

и мой класс ItemController

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.');
    }

Ответ для второй попытки метода:

{
    "success": true,
    "data": [
        {
            "Product_id": null,
            "product_name": null
        },
        {
            "Product_id": null,
            "product_name": null
        }
    ],
    "message": "Items retrieved successfully."
}

person Khal    schedule 25.07.2020    source источник
comment
один из вариантов - создать ресурс json вручную так, как вы хотите. См. здесь: laravel.com/docs/7.x/eloquent-resources #письменные-ресурсы. Другой вариант — использовать конструктор запросов для создания запроса вручную и выбора необходимых столбцов.   -  person user3532758    schedule 25.07.2020
comment
Это работает только для одного, если написать для обоих в посте ресурсов человек не будет загружать значения. $items= Предметы::все(); но для обоих, если я сделаю $items= Items::with(prod)->get() не будет работать.   -  person Khal    schedule 25.07.2020
comment
Можете ли вы поделиться своими изменениями в классе ItemResource?   -  person user3532758    schedule 25.07.2020
comment
@user3532758 user3532758 Спасибо, я обновил свой вопрос, я задал второй метод, пожалуйста, проверьте, что все дает null Спасибо за помощь   -  person Khal    schedule 25.07.2020
comment
Попробуйте это: получить предметы с прод. Затем в классе ресурсов под строкой product_id 'sold' => $this->prod->sold, но вам нужно иметь класс ItemCollection отдельно. Проверьте laravel.com/docs/7.x/eloquent-resources#resource -коллекции. Прочтите о классе сбора ресурсов. Если у вас все еще есть трудности, я опубликую ответ для вас   -  person user3532758    schedule 25.07.2020
comment
@user3532758 user3532758 с ресурсом также не загружается, простой способ поможет мне большое спасибо.   -  person Khal    schedule 25.07.2020
comment
ок плохо опубликовать ответ   -  person user3532758    schedule 25.07.2020


Ответы (1)


Во-первых, вам нужно вручную создать возвращаемый массив в вашем классе ItemsResouce, например:

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

Далее вам нужно создать класс сбора ресурсов, вы можете назвать его ItemCollection. Вы можете использовать команду php artisan make:resource ItemCollection для создания класса. Класс должен выглядеть так:

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);
    }
}

И в методе index вашего контроллера вы можете вернуть ответ следующим образом:

//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
}
person user3532758    schedule 25.07.2020