Rumah  >  Soal Jawab  >  teks badan

Cara menggunakan koleksi pada sumber Laravel pada model yang sama

Kami sedang membangunkan ciri dalam codotto.com di mana pengguna boleh meninggalkan komen pada pertemuan IT. Setiap komen boleh ada jawapan. Kami hanya membenarkan satu tahap jawapan yang mendalam, contohnya:

- Comment 1
  - Answer to comment 1
  - Answer to comment 1
- Comment 2
  - Answer to comment 2
  - Answer to comment 2

Saya mempunyai struktur pangkalan data berikut:

// meetup_messages
- id
- user_id
- meetup_id
- meetup_message_id (nullable) -> comments that do not answer will have this set to nullable

Dalam model saya, saya akan answers 定义为 HasMany hubungan:

class MeetupMessage extends Model
{
  // ...

  public function answers(): HasMany
  {
      return $this->hasMany(self::class, 'meetup_message_id');
  }
}

Kemudian pada pengawal saya, saya mendapat semua komen tanpa jawapan:

public function index(
        IndexMeetupMessageRequest $request,
        Meetup $meetup,
        MeetupMessageService $meetupMessageService
    ): MeetupMessageCollection
    {
        $meetupMessages = MeetupMessage::with([
            'user',
            // 'answers' => function ($query) {
            //   $query->limit(3);
            // }
            'answers'
        ])
            ->whereNull('meetup_message_id')
            ->whereMeetupId($meetup->id)
            ->paginate();

        return new MeetupMessageCollection($meetupMessages);
    }

Kemudian pada MeetupMessageCollection saya:

class MeetupMessageCollection extends ResourceCollection
{
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

Kemudian pada MeetupMessageResource saya:

<?php

namespace AppHttpResources;

use IlluminateHttpResourcesJsonJsonResource;
use IlluminateSupportCollection;

class MeetupMessageResource extends JsonResource
{
    public function toArray($request)
    {
        return collect([
            // 'answers' => new MeetupMessageCollection($this->whenLoaded('answers')),
        ])
            ->when(
                is_null($this->meetup_message_id) && $this->relationLoaded('answers'),
                function (Collection $collection) {
                    $collection->put('answers', MeetupMessageCollection::collection($this->answers));
                }
            );
    }
}

Tetapi saya mendapat ralat berikut: Panggil ke kaedah yang tidak ditentukan AppModelsMeetupMeetupMessage::mapInto(). Bagaimanakah saya masih boleh menggunakan 调用未定义的方法 AppModelsMeetupMeetupMessage::mapInto()。我如何通过将 answers 传递给它来仍然使用 MeetupMessageCollection dengan menghantar jawapan kepadanya?

P粉029327711P粉029327711265 hari yang lalu391

membalas semua(1)saya akan balas

  • P粉696146205

    P粉6961462052024-01-03 09:05:21

    Seperti yang @matialauriti nyatakan, anda tidak boleh menggunakan koleksi sumber dalam koleksi dalam Laravel

    class MeetupMessageResource extends JsonResource
    {
      public function toArray()
      {
        return [
          'answers' => new MeetupMessageCollction($this->answers) // ❌ You can't do this
        ]
      }
    }
    

    Penyelesaian saya ialah menarik borang sumber saya ke dalam kaedah peribadi dan menggunakannya semula apabila answers hadir:

    class MeetupMessageResource extends JsonResource
    {
      public function toArray($request)
      {
          return collect($this->messageToArray($this->resource))
              ->when($this->relationLoaded('user'), function (Collection $collection) {
                  $collection->put('user', $this->userToArray($this->user));
              })
              // ✅ Now I don't need to use Resources inside my API Resource class
              ->when(
                  is_null($this->meetup_message_id) && $this->relationLoaded('answers'),
                  function (Collection $collection) {
                      $answers = $this
                          ->answers
                          ->map(function (MeetupMessage $answer) {
                              return array_merge(
                                  $this->messageToArray($answer),
                                  ['user' => $this->userToArray($answer->user)]
                              );
                          });
                      $collection->put('answers', $answers);
                  }
              );
      }
    
      private function messageToArray(MeetupMessage $meetupMessage): array
      {
          return [
              'id' => $meetupMessage->id,
              'message' => Purify::config(MeetupMessageService::CONFIG_PURIFY)->clean($meetupMessage->message),
              'answersCount' => $this->whenCounted('answers'),
              'createdAt' => $meetupMessage->created_at,
          ];
      }
    }
    

    balas
    0
  • Batalbalas