ساخت eloquent api resource قسمت سوم

54
ساخت eloquent api resource قسمت سوم

در مطلب قبل توضیحاتی در رابطه با استفاده از روابط در api resource داده شد.
حالا در این مطلب آموزش استفاده از شرط ها در api resource را بررسی میکنیم.


Conditionals When Working With Resources :


1. whenLoaded

زمانی که شما از یک مدل استفاده میکنید و اطلاعات آن را نمایش میدهید، ممکن است بخواهید یکی از relation های آن را هم، همزمان load کنید.
فکر کنید یک مدل داریم به ProductCategory که این مدل رابطه oneToMany با مدل Product دارد.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ProductCategory extends Model
{

    public function products()
    {
        return $this->hasMany(Product::class, 'category_id');
    }
}

مدل Product را ببینید:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{

    public function category()
    {
        return $this->belongsTo(ProductCategory::class);
    }
   
}

همچنین resource مربوط به ProductCategory به شکل زیر است:

<?php

namespace App\Http\Resources\Client;

use Illuminate\Http\Resources\Json\JsonResource;

class ProductCategory extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request $request
     * @return array
     */
    public function toArray($request)
    {
        
        return [
            'id' => $this->id,
            'title' => $this->title,
        ];
    }
}



حالا یک route تعریف میکنیم به شکل زیر که اولین category را نمایش دهد:

use App\Http\Resources\Client\ProductCategory;

Route::get('/category', function () {
    return new ProductCategory(\App\ProductCategory::first());
});

خروجی بالا به شکل زیر است:

{
   data: {
       id: 1,
       title: "First Category",
   }
}

حالا با استفاده از eager loading اگر بخواهید از products را همراه با دسته بندی load کنید به شکل زیر عمل کنید:

use App\Http\Resources\Client\ProductCategory;

Route::get('/p', function () {
    return new ProductCategory(\App\ProductCategory::first()->load('products'));
});

و سپس resource هم به شکل زیر تغییر دهید:

<?php

namespace App\Http\Resources\Client;

use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Client\Product as ProductResource;

class ProductCategory extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request $request
     * @return array
     */
    public function toArray($request)
    {
        
        return [
            'id' => $this->id,
            'title' => $this->title,
            'product' => ProductResource::collection($this->whenLoaded('products')),
        ];
    }
}

حالا دوباره route را صدا میزنیم. خروجی به شکل زیر است:

{
  data: {
     id: 1,
     title: "First Category",
     products: [
         {
            id: 1,
            code: "3250565",
            title: "First Product",
         },
         {
            id: 2,
            code: "7361082",
            title: "Second Product",
         },
    ],
  }
}

 میبینید که با استفاده از whenLoaded زمانی که eager loading را روی مدل صدا بزنید، روابط load خواهند شد.


2. mergeWhen

حالا اگر شما بخواهید با استفاده از یک شرط خاص، روابط load شوند، میتوانید از متد استفاده کنید.
برای مثال route زیر را در نظر بگیرید:

 https://laraman.ir/api/category

مشخص است که این route اطلاعات مرتبط با category (ها) را برمیگرداند.
حالا اگر بخواهید، زمانی که نیاز داشتید محصولات را هم همزمان برگردانید و نمایش دهید میتوانید یک شرط ساده تنظیم کنید.

برای مثال، میتوانید به صورت پارامتر در url متغیر products را set کنید و از این متغیر استفاده کنید:

https://laraman.ir/api/category?products=true

این url برای زمانی کاربردی است که بخواهید دسته ها و محصولات را load کنید ولی مزیت این قسمت این است که تنها زمانی که به محصولات نیاز داشته باشید load میشوند نه همیشه ! که این قضیه در توسعه api به شما خیلی کمک خواهد کرد.

حالا به resource دقت کنید و ببینید که به چه صورت از mergeWhen استفاده شده است:

<?php

namespace App\Http\Resources\Client;

use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Client\Product as ProductResource;

class ProductCategory extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request $request
     * @return array
     */
    public function toArray($request)
    {
        $flag = ($request->has('products') ? true : false);

        return [
            'id' => $this->id,
            'title' => $this->title,
            'products' => $this->mergeWhen($flag,
                ProductResource::collection($this->products))
        ];
    }
}

این متد به عنوان پارامتر اول boolean میپذیرد و به عنوان پارامت دومر مقداری را میپذیرد که شما قرار است به خروجی اضافه کنید.

نکات دیگری هم در api resource وجود دارد که با کمی مطالعه میتوانید آنها را پیدا کنید و استفاده کنید.
امیدوارم این آموزش به شما کمک کرده باشد.
اگر سوالی داشتید میتوانید از قسمت نظرات بپرسید.


نظرات
هنوز نظری ثبت نشده است
برای ثبت نظر ابتدا وارد سایت شوید