Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New generic resources from 0.5.3 #508

Closed
danijelk opened this issue Mar 24, 2020 · 12 comments
Closed

New generic resources from 0.5.3 #508

danijelk opened this issue Mar 24, 2020 · 12 comments

Comments

@danijelk
Copy link

With the PR from #470 we're having issues on our resources.

With level 1 we get this

./vendor/bin/phpstan analyse --no-progress app/Http/Resources/CompanyResource.php                                                                                                                              
Note: Using configuration file phpstan.neon.
 ------ -----------------------------------------------------------------------------------------
  Line   CompanyResource.php
 ------ -----------------------------------------------------------------------------------------
  16     Access to an undefined property App\Http\Resources\CompanyResource::$id.
  17     Access to an undefined property App\Http\Resources\CompanyResource::$parent_id.
  18     Access to an undefined property App\Http\Resources\CompanyResource::$name.
  19     Access to an undefined property App\Http\Resources\CompanyResource::$address.
  20     Access to an undefined property App\Http\Resources\CompanyResource::$city.
  21     Access to an undefined property App\Http\Resources\CompanyResource::$countryInfo.
  22     Access to an undefined property App\Http\Resources\CompanyResource::$custom_company_id.
 ------ -----------------------------------------------------------------------------------------

Tried different combos but can't figure out the new usage


namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @extends JsonResource<Company>
 */
class CompanyResource extends JsonResource
{
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @extends JsonResource<Models\Company>
 */
class CompanyResource extends JsonResource
{


namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @extends JsonResource
 */
class CompanyResource extends JsonResource
{

Any pointers @mr-feek ?

@canvural
Copy link
Collaborator

canvural commented Mar 24, 2020

Hi,

When you are passing the model name to JsonResource generic, it should have the full namespace. Or if you imported the model you can use just the class name.

For example:

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @extends JsonResource<\App\Models\Company>
 */
class CompanyResource extends JsonResource
{
}

or

use Illuminate\Http\Resources\Json\JsonResource;
use App\Models\Company;

/**
 * @extends JsonResource<Company>
 */
class CompanyResource extends JsonResource
{
}

@danijelk
Copy link
Author

Thanks for reply, tested both cases, still the same issue on our side.

namespace App\Http\Resources;

use App\Models\Company;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @extends JsonResource<Company>
 */
class CompanyResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'parent_id' => $this->parent_id,
            'name' => $this->name,
            'address' => $this->address,
            'city' => $this->city,
            'country' => $this->countryInfo->name,
            'custom_company_id' => $this->custom_company_id,
        ];
    }
}


  Line   CompanyResource.php
 ------ -----------------------------------------------------------------------------------------
  16     Access to an undefined property App\Http\Resources\CompanyResource::$parent_id.
  17     Access to an undefined property App\Http\Resources\CompanyResource::$name.
  18     Access to an undefined property App\Http\Resources\CompanyResource::$address.
  19     Access to an undefined property App\Http\Resources\CompanyResource::$city.
  20     Access to an undefined property App\Http\Resources\CompanyResource::$countryInfo.
  21     Access to an undefined property App\Http\Resources\CompanyResource::$custom_company_id.

@canvural
Copy link
Collaborator

Are the property types correctly read in other files for models? If not, do you have the database migration files in the default Laravel place?

@danijelk
Copy link
Author

No for models (will use ide-helper now to test, we use the ide_helper_models.php instead)
No for migration file.

-- edit

ok works with he definitions in the model, makes sense now why it didn't work thanks! Would be golden if larastan could read ide_helper file 🥇

@canvural
Copy link
Collaborator

Do you have the migration files somewhere else or you don't have it at all? I'm asking because maybe it is something we can solve if it is something that can affect other users.

Glad, it's working for you with the properties written in models. So, I'm closing this.

@danijelk
Copy link
Author

Yes we have the migrations in another nonstandard folder. We make an sql dump of our db and use that as we surpassed > 100migrations, this way we only have 1 sql file with latest tables which is faster to load for CI.

Easiest way I see it is to scan the ide helper file since we have to keep our models clean sadly 👍

@canvural
Copy link
Collaborator

canvural commented Mar 25, 2020

I did not try but maybe you can add the generated models file to stubs of PHPStan. Like this

phpstan.neon

parameters:
	stubFiles:
		- _ide_helper_models.php
	...

This will tell PHPStan to read only the phpdocs from this file.

@danijelk
Copy link
Author

Great idea, tested it with different namespaces for company, no go sadly.

@mr-feek
Copy link
Contributor

mr-feek commented Mar 25, 2020

Heyo -- perhaps for now you can regain the prior functionality by reenabling JsonResource to be a universal object crate

https://github.com/nunomaduro/larastan/pull/470/files#diff-300c6013fb9bc1bc02b8fbd9fb9ac2b0L10

Try adding that to your phpstan.neon.

@danijelk
Copy link
Author

Awesome

   universalObjectCratesClasses:
        - Illuminate\Http\Resources\Json\JsonResource

works, although not as good as an actual check that the new version does, but this will push us onwards for now, thanks.

@loureirorg
Copy link

I just ran into this same issue. For me adding a @mixin <Model> fixed the Access to an undefined property:

/** @mixin User */
class UserResource extends JsonResource
{

But it didn't work for scoped relationships:

// UserResource.php
$books = $this->books()->active();

It returned this error:

Call to an undefined method Illuminate\Database\Eloquent\Relations\HasMany::active()

Models:

// User.php
public function books(): HasMany
{
    return $this->hasMany(Book::class);
}
// Book.php
public function scopeActive(Builder $query): Builder
{
    return $query->where('is_active', true);
}

To fix it, I added a @return PHPDoc to the relationship declaration:

// User.php

/** @return HasMany<Book> */
public function books(): HasMany
{

Alternatively, there's also this ugly solution:

/** @var User */
$that = $this;

$books = $that->books()->active();

Is there a better way besides ide_helper or universalObjectCratesClasses?

@Meklad
Copy link

Meklad commented Sep 19, 2022

Awesome

   universalObjectCratesClasses:
        - Illuminate\Http\Resources\Json\JsonResource

works, although not as good as an actual check that the new version does, but this will push us onwards for now, thanks.

This works fine, anyone who faces this issue with Model Resources can add this to phpstan.neon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants