【问题标题】:how to use collection on same model laravel resources如何在相同模型的 laravel 资源上使用集合
【发布时间】:2022-10-30 21:40:14
【问题描述】:

我们目前正在codotto.com 中开发一项功能,用户可以在其中对 IT 聚会发表评论。每个评论都可以有一个答案。我们只允许一个层次的深度答案,比如:

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

我有以下数据库结构:

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

在我的模型中,我将answers 定义为HasMany 关系:

class MeetupMessage extends Model
{
  // ...

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

然后在我的控制器上,我得到所有没有答案的 cmets:


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);
    }

然后在我的MeetupMessageCollection 上:

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

然后在我的MeetupMessageResource 上:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Collection;

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));
                }
            );
    }
}

但我收到以下错误:Call to undefined method App\\Models\\Meetup\\MeetupMessage::mapInto()。我怎样才能通过将answers 传递给MeetupMessageCollection 来使用它?

【问题讨论】:

  • @Sumitkumar 感谢您的评论,但此评论完全没有问题。我不是要求更改数据库架构
  • 你在混合东西,你不能使用普通的资源集合到资源中......documentation 是不言自明的,你不明白什么?
  • @matiaslauriti 从来没有进入过你不能在资源中使用资源的文档。感谢您指出这一点。我已将逻辑移到私有方法中以保持一致性。
  • 抱歉,我并没有完全提供帮助。我对您想要实现的目标感到非常困惑(基于您在其中混合的代码)。你能在哪里解决问题?

标签: php laravel laravel-resource


【解决方案1】:

正如@matialauriti 指出的那样,您不能在 Laravel 的集合中使用资源集合

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

我的解决方案是将我的资源结构拉到一个私有方法并在存在answers 时重新使用它:

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));
          })
          ->when(
              // ✅ Now I don't need to use Resources inside my API Resource class
              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,
      ];
  }
}

【讨论】:

    猜你喜欢
    • 2022-07-26
    • 2019-09-28
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2021-08-11
    • 2020-07-17
    相关资源
    最近更新 更多