Laravel Много к одному в ресурсе

#laravel #resources #laravel-api #laravel-relations #laravel-resource

Вопрос:

Я использую laravel 8 и имею 3 таблицы: Продукты, Цена продукта и издатель продуктов: введите описание изображения здесь

это моя модель продуктов для этих отношений:

 public function lastPrice(){  return $this-gt;hasMany(ProductPrice::class)-gt;where('status','active')-gt;orderBy('created_at','DESC')-gt;distinct('publisher_id'); }  

и это моя модель productsPrice для отношений с издателем:

 public function getPublisher(){  return $this-gt;belongsTo(ProductsPublisher::class,'publisher_id'); }  

теперь я хочу использовать ресурс laravel для своего api, я написал ресурс продуктов:

 public function toArray($request) {  return [  'id' =gt; $this-gt;id,  'price' =gt; lastPrice::make($this-gt;lastPrice),  'status' =gt; $this-gt;status,  'slug' =gt; $this-gt;slug,  'title' =gt; $this-gt;title,  'description' =gt; $this-gt;description,  'txt' =gt; $this-gt;txt,  'lang' =gt; $this-gt;lang,  'created_at' =gt; $this-gt;created_at,  'updated_at' =gt; $this-gt;updated_at,  ];  

но на ресурсе lastPrice, когда я писал так:

 return [  'id' =gt; $this-gt;id,  'main_price' =gt; $this-gt;main_price  ];  

это дает мне эту ошибку:

Свойство [id] не существует в этом экземпляре коллекции.

когда я использую этот код:

 return parent::toArray($request);  

получите ответ, но поскольку мне нужно использовать другое отношение в моей последней публикации для издателей, я не могу использовать этот код и должен возвращать свои данные отдельно. Что я должен делать? Спасибо

Правка 1: это мой код контроллера:

 $products = Product::where('id',$id)-gt;where('slug',$slug)-gt;where('status','confirm')-gt;first();  if(!$products){  return $this-gt;sendError('Post does not exist.');  }else{  return $this-gt;sendResponse(new AppHttpResourcesProductsProducts($products), 'Posts fetched.');  }  

and this is sendResponse amp; sendError:

 public function sendResponse($result, $message) {  $response = [  'success' =gt; true,  'data' =gt; $result,  'message' =gt; $message,  ];   return response()-gt;json($response, 200); }  public function sendError($error, $errorMessages = [], $code = 404) {  $response = [  'success' =gt; false,  'message' =gt; $error,  ];   if(!empty($errorMessages)){  $response['data'] = $errorMessages;  }   return response()-gt;json($response, $code); }  

Спасибо.


Правка 2: я изменил свой ресурс lastPrice на функцию отображения на это, и моя проблема решена, но я думаю, что это не чистый способ, есть идея получше?

 $old_data = parent::toArray($request);  $co = 0;  $new_data = [];  foreach ($old_data as $index){  $publisher_data = Cache::remember('publisher'.$index['publisher_id'], env('CACHE_TIME_LONG') , function () use ($index) {  return ProductsPublisher::where('id' , $index['publisher_id'])-gt;first();  });  $new_data[$co]['main_prices'] = $index['main_price'];  $new_data[$co]['off_prices'] = $index['off_price'];  $new_data[$co]['publisher'] = SinglePublisher::make($publisher_data);  $new_data[$co]['created_at'] = $index['created_at'];   $co  ;  }  return $new_data;  

Комментарии:

1. Не могли бы вы добавить к своему вопросу, что вы передаете этим ресурсам API

2. @muhamadhhassan: спасибо за ваш ответ, я прилагаю свой код контроллера.

3. Ваши имена ресурсов не соответствуют соглашению, но если оно не расширяется IlluminateHttpResourcesJsonJsonResource , оно не будет расширяться, и вы будете расширяться IlluminateHttpResourcesJsonResourceCollection , и это принимает коллекцию, а не объект

4. @muhamadhhassan: спасибо за ваш ответ, мой ресурс продукта возвращает данные, когда я использую это: верните родителя::toArray (запрос$); в моем ценовом ресурсе. но мне нужны возвращаемые данные отдельно в ценовом ресурсе.