1

i have resource which returns the user quiz status it looks something like this

$users = Users::with('UserQuiz')->get();
return response(['users'=> UserResource::collection($users ) ]);

inside the resource i need to return user information and their quizzes

$passedQuizzes = [] ;
foreach($this->UserQuiz as $userQuiz )
{
   if($userQuiz->score > 50 )
      $passedQuizzes[] = $userQuiz  ; 
}


$totalQuiz = Quiz::count();


return [

  'id' => $this->id , 
  'name' => $this->name , 
  'email' => $this->email , 
  
  'quiz'=>[
      'total'=> $totalQuiz , 
      'passed' => count($passedQuizzes)
  ]
  
];

i need to show the total number of quiz and how many this user has passed ... so i need an extra query inside my resource which is not a good idea considering im running the same query over and over

so i need to somehow inject the totalQuiz from controller to resource so , i've red about additional in the doc so i guess it should be something like

$users = Users::with('UserQuiz')->get();
$totalQuiz = Quiz::count();

return response(['users'=> UserResource::collection($users )->additional(['totalQuiz' => $totalQuiz ]) ]);

but i have no idea how to access this additional data inside resource i want to be able to do something like

return [

  'id' => $this->id , 
  'name' => $this->name , 
  'email' => $this->email , 
  
  'quiz'=>[
      'total'=> $this->additional->totalQuiz , 
      'passed' => count($passedQuizzes)
  ]
  
];

this is a very common problem i wonder why there are not many answers online about this problem

this is the only thing i can find online which doesnt seem to have a suitable answer

Additional data in Laravel Resource

hretic
  • 999
  • 9
  • 36
  • 78
  • You will have to overwrite the constructor of your Resource to allow more arguments, or create an own static method that creates the resource and adds the other arguments. – Aless55 Feb 22 '23 at 18:56

1 Answers1

0

The following code adds a static method to your Resource. This method can take as many additional paramters as you'd like. I added the $totalQuiz param for demonstration purpose.

   //add static variable
   public static $totalQuiz;

   /**
     * Create a new anonymous resource collection.
     *
     * @param  mixed  $resource
     * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
     */
    public static function customCollection($resource, $totalQuiz)
    {
        self::$totalQuiz = $totalQuiz;

        return tap(new AnonymousResourceCollection($resource, static::class), function ($collection) {
            if (property_exists(static::class, 'preserveKeys')) {
                $collection->preserveKeys = (new static([]))->preserveKeys === true;
            }
        });
    }

You can then create the Resource with this new static method instead of the static UserResource::collection($users) method.

UserResource::customCollection($users, $totalQuiz);
Aless55
  • 2,652
  • 2
  • 15
  • 26