Laravel 5.6: استدعاء العلاقات البليغة يغير بيانات المجموعة

0

هل هناك طريقة لاستدعاء طرق العلاقة البليغة بدون تغيير المجموعة البليغة الأصلية التي تعمل عليها الطريقة؟ يجب علي حاليًا استخدام مجموعة مؤقتة لتشغيل الطريقة غير قابلة للتغيير ولمنع إضافة سجل كامل ذي صلة إلى إرجاع الاستجابة:

$result = Item::find($id);
$array = array_values($result->toArray());
$temp = Item::find($id);
$title = $temp->article->title;

dd($temp); //This prints entire article record added to the temp collection data.

array_push($array, $title);

return response()->json($array);

3 الاجابة

1
افضل جواب

أنت لا تتعامل مع المجموعات هنا ولكن مع النماذج. Item::find($id) سوف تحصل على شيء من الدرجة Item (أو null إذا لم يتم العثور عليها).

على حد علمي ، لا توجد طريقة لتحميل علاقة دون تخزينها في موصل العلاقة. ولكن يمكنك دائمًا إلغاء تعيين الموصل مرة أخرى لحذف العلاقة المحملة (من الذاكرة).

على سبيل المثال ، تعطي هذه العملية:

$result = Item::find($id);
$title = $result->article->title;
unset($result->article);

return response()->json(array_merge($result->toArray(), [$title]));

يعمل أعلاه ولكن ليس رمز لطيف للغاية. بدلاً من ذلك ، يمكنك القيام بأحد الأمور الثلاثة التالية:

  1. استعمال attributesToArray() بدلا من toArray() (الذي يدمج الصفات والعلاقات):

    $result = Item::find($id);
    return response()->json(array_merge($result->attributesToArray(), [$result->article->title]));
    
  2. أضف طريقة getter الخاصة بك على Item الطبقة التي ستعرض جميع البيانات التي تريدها. ثم استخدمه في وحدة التحكم:

    class Item
    {
        public function getMyData(): array
        {
            return array_merge($this->attributesToArray(), [$this->article->title]);
        }
    }
    

    مراقب:

    $result = Item::find($id);
    return response()->json($result->getMyData());
    
  3. إنشاء مورد الاستجابة الخاص بك:

    <?php
    
    namespace App\Http\Resources;
    
    use Illuminate\Http\Resources\Json\JsonResource;
    
    class ItemResource extends JsonResource
    {
        public function toArray($request)
        {
            return [
                'id' => $this->id,
                'name' => $this->name,
                'title' => $this->article->title,
                'author' => $this->article->author,
                'created_at' => $this->created_at,
                'updated_at' => $this->updated_at,
            ];
        }
    }
    

    والتي يمكن استخدامها بعد ذلك على النحو التالي:

    return new ItemResource(Item::find($id));
    

أنظف نهج هو الخيار 3 . بالطبع يمكنك أيضا استخدام $this->attributesToArray() بدلاً من تعداد الحقول ، ولكن تعدادها سيعطيك الأمان في المستقبل مع الأخذ في الاعتبار أنك قد تمدد النموذج ولا تريد فضح الحقول الجديدة.

:مؤلف
1
افضل جواب

ليس هناك على حد علمي. عند التعامل مع مخرجات النموذج ، أقوم عادةً بإنشائها يدويًا على النحو التالي:

$item = Item::find($id);

$result = $item->only('id', 'name', 'description', ...);
$result['title'] = $item->article->title;

return $result; 

إذا كنت بحاجة إلى مزيد من القوة أو حل قابل لإعادة الاستخدام ، فإن الموارد هي أفضل رهان لك.

https://laravel.com/docs/5.6/eloquent-resources#concept-overview

:مؤلف
1
افضل جواب

أرى طريقتين لتحقيق ذلك.

أولاً ، يمكنك استخدام مورد بليغ. بشكل أساسي ، سيسمح لك بإعادة ما تريده بالضبط من النموذج ، لذلك في حالتك ، ستتمكن من استبعاد المقالة. يمكنك العثور على الوثائق هنا .

الطريقة الثانية جديدة جدًا ولا تزال غير موثقة (كما أعرف ،) ولكنها في الواقع تعمل بشكل جيد. يمكنك استخدام طريقة unsetRelation. لذا في حالتك ، عليك فقط القيام بما يلي:

$article = $result->article; // The article is loaded
$result->unsetRelation('article'); // It is unloaded and will not appear in the response

يمكنك العثور على وثائق unsetRelation هنا

:مؤلف
فوق
قائمة طعام