orm icon indicating copy to clipboard operation
orm copied to clipboard

Laravel paginated collection resource issue

Open KPKoch opened this issue 5 years ago • 3 comments

I do have a new behavior without any app code changes. Before update to L6.18 (don't know the exact version before) it worked as exspected. Then I did upgrade to L7 to get the latest laraveldoctrine adaptions. But I also got the same behaviour.

Context: I create a paginated Result from Doctrine via:

 return new $this->modelCollection ($this->em->getRepository($this->modelNameFQ)->getAllPaginated($defaults));

In modelcollection I do the normal to_Array stuff to 'select' the fields, as in:

   public function toArray($request)
    {
        $data = [];
        foreach ($this->collection as $item) {
            $data[] = new ModelResource($item);
        }
        return $data;
    }

This worked the past years, but not anymore. I am pretty clueless - just outcommenting the line in vendor is not my prefered solution ;).

Package version, Laravel version

latest laraveldoctrine package, Laravel 6.18+

"beberlei/DoctrineExtensions": "^1.2.6",
"laravel-doctrine/acl": "^1.1.1",
"laravel-doctrine/extensions": "^1.2.0",
"laravel-doctrine/fluent": "^1.1.6",
"laravel-doctrine/migrations": "^2.0",
"laravel-doctrine/orm": "^1.6",
"laravel-doctrine/scout": "master",

Expected behaviour

Returning a JSON resource

Actual behaviour

message: Undefined property: App\Models<model>::$resource

Steps to reproduce the behaviour

I can return to the old, successful behavior if I uncomment line ~29 in vendor/laravel/framework/src/Illuminate/Http/Resources/Json/PaginatedResourceResponse.php

), function ($response) use ($request) {
            $response->original = $this->resource->resource->map(function ($item) {
        //        return is_array($item) ? Arr::get($item, 'resource') : $item->resource;
            });

KPKoch avatar May 09 '20 12:05 KPKoch

"fixed it" by adding the attribute

   public $resource;

to the models. Still, can anyone bring some light into this?

KPKoch avatar May 09 '20 13:05 KPKoch

I have the same issue, i opened a ticket to laravel https://github.com/laravel/framework/issues/35791 but they close it. I didn't upgrade my doctrine dependency, even when i did the issue persists.

I added the public $resource attribute to the models, but still is not working for me.

[UPDATE] i fixed it by doing this:

foreach($items as $item) {
            $item->resource = null;
        }

Awful fix... but at least it's working

EM-LilianaIturribarria avatar Jan 06 '21 17:01 EM-LilianaIturribarria

  • Laravel 7.30.6
  • PHP 7.4.29

Same problem. I just using QueryBuilder as $resource and paginate this:

class BarCollectionSearchResource extends ResourceCollection
{
    protected YandexSearchDTO $dto;

    public function __construct(YandexSearchDTO $dto)
    {
        $this->dto = $dto;

        parent::__construct($this->getResource());
    }

    public function toArray($request)
    {
        return $this->resource->map(function(stdClass $bar) {
            $bar = (array) $bar;

            return [
                'url' => \Base_Url::toBarCard($bar),
                'name' => $this->setHighlight($bar['name']),
                'address' => $this->setHighlight($bar['address']),
                'vip' => \Bar_Service_Tariff::isActive($bar['id']),
                //etc transformations
            ];
        });
    }

    protected function getResource(): AbstractPaginator
    {
        $builder = DB::table('bar_struct as s')
            //some of joins
            ->select() //some of selects
            ->where() //some of where
            ->groupBy('s.id');

        return $builder->paginate($this->dto->perPage, ['*'], 'page', $this->dto->page);
    }

    protected function setHighlight(string $where = null):? string
    {
 	return preg_replace('~(' . $this->dto->query . ')~iu', "<em>$1</em>", $where);
    }
}

But got error Undefined property: stdClass::$resource when call controller:

class YandexSearchController extends Controller
{
    public function indexAction(Request $request)
    {
        return new BarCollectionSearchResource(
            new YandexSearchDTO($request)
        );
    }
}

https://skr.sh/sILFeRgmw0y If comment this code return is_array($item) ? Arr::get($item, 'resource') : $item->resource; all is ok.

P.S. Fixed by adding ->selectRaw("'resource'") into my builder...

projct1 avatar Feb 11 '23 08:02 projct1