1

I use laravel 8 & have 3 table: Products, ProductPrice & ProductsPublisher: enter image description here

this is my Products model for this relationship:

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

and this is my productsPrice model for publisher relationship:

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

now, i want to use laravel resource for my api, i wrote products resource:

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

but in lastPrice resource, when i wrote like this:

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

it give me this error:

Property [id] does not exist on this collection instance.

when i use this code:

return parent::toArray($request);

get response but because i need to use another relationship in my lastPirce for publishers, i cant use that code and should return separately my data. What i should to do? thanks

Edit 1: this is my Controller Code:

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

and this is sendResponse & sendError:

    public function sendResponse($result, $message)
{
    $response = [
        'success' => true,
        'data'    => $result,
        'message' => $message,
    ];

    return response()->json($response, 200);
}

public function sendError($error, $errorMessages = [], $code = 404)
{
    $response = [
        'success' => false,
        'message' => $error,
    ];

    if(!empty($errorMessages)){
        $response['data'] = $errorMessages;
    }

    return response()->json($response, $code);
}

thanks.


Edit 2: i change my lastPrice Resource toArray function to this and my problem solved, but i think this isn't a clean way, any better idea?

    $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'])->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;
Soroush Tayyebi
  • 137
  • 1
  • 9
  • Could you add to your question what are you passing to these API resources – muhamadhhassan Oct 30 '21 at 08:39
  • @muhamadhhassan: thanks for your reply, i attach my controller code. – Soroush Tayyebi Oct 30 '21 at 08:43
  • Your resource names is not following the convention but if it doesn’t extend `Illuminate\Http\Resources\Json\JsonResource` it will not and you will be extending `Illuminate\Http\Resources\Json\ResourceCollection` and this accepts a collection not an object – muhamadhhassan Oct 30 '21 at 08:52
  • @muhamadhhassan: thanks for your reply, my Product resource return data when i use this: return parent::toArray($request); in my Price Resource. but i need return data separately in price resource. – Soroush Tayyebi Oct 30 '21 at 09:46

0 Answers0