#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 (запрос$); в моем ценовом ресурсе. но мне нужны возвращаемые данные отдельно в ценовом ресурсе.