Skip to content

[12.x] use "class-string" type for using pivot model #55053

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

Merged
merged 4 commits into from
Mar 18, 2025

Conversation

browner12
Copy link
Contributor

the using property of the BelongsToMany class is not just a string, but specifically a class string, so we'll document it as such.

helps in places where static methods are being called on the string

still a little new to the generics declarations, so LMK if I need to adjust anything on that.

the `using` property of the `BelongsToMany` class is not just a string, but specifically a class string, so we'll document it as such.

helps in places where [static methods are being called on the string](https://github.com/laravel/framework/blob/12.x/src/Illuminate/Database/Eloquent/Relations/MorphToMany.php#L160)
apparently can't use Traits as types

Co-authored-by: Jeffrey Angenent <1571879+devfrey@users.noreply.github.com>
@browner12
Copy link
Contributor Author

if someone could point me in the right direction on the generics stuff here, that would be much appreciated. about time I get better at this stuff I guess.

@taylorotwell
Copy link
Member

Looks like the type tests failed.

@taylorotwell taylorotwell marked this pull request as draft March 17, 2025 20:13
@AndrewMast
Copy link
Contributor

@browner12 Take a look at browner12/framework#1 to see if that fixes the tests

Fixed docblocks for generic to pass type test
@browner12 browner12 marked this pull request as ready for review March 17, 2025 23:21
@browner12
Copy link
Contributor Author

thanks @AndrewMast for the fix!

@taylorotwell taylorotwell merged commit 86f8574 into laravel:12.x Mar 18, 2025
39 checks passed
@browner12 browner12 deleted the AB-belongs-to-many-class-string branch March 18, 2025 02:45
@devfrey
Copy link
Contributor

devfrey commented Mar 18, 2025

Is there any benefit to these generics in userland code? Because the new @template TPivotModel requires every reference to BelongsToMany (i.e. every model relation method) to also include the pivot type, even though (most of the time) it will be the default Pivot model.

PHPStan supports template defaults, so we could make it optional to provide a more specific class for TPivotModel using:

 /**
  * @template TPivotModel of \Illuminate\Database\Eloquent\Relations\Pivot = \Illuminate\Database\Eloquent\Relations\Pivot
  */

@amants
Copy link

amants commented Mar 19, 2025

@devfrey indeed. It also broke all my many-to-many relations phpstan.

Method App\Domain\User\Models\User::roles() should return Illuminate\Database\Eloquent\Relations\BelongsToMany<App\Domain\Role\Models\Role, $this(App\Domain\User\Models\User)> but returns  
         Illuminate\Database\Eloquent\Relations\BelongsToMany<App\Domain\Role\Models\Role, $this(App\Domain\User\Models\User), Illuminate\Database\Eloquent\Relations\Pivot>.                         
         🪪  return.type  

When adding Pivot to the PHPDoc:

Generic type Illuminate\Database\Eloquent\Relations\BelongsToMany<App\Domain\Role\Models\Role, $this(App\Domain\User\Models\User), Illuminate\Database\Eloquent\Relations\Pivot> in PHPDoc tag @return specifies 3 template types, but  
         class Illuminate\Database\Eloquent\Relations\BelongsToMany supports only 2: TRelatedModel, TDeclaringModel    

@AJenbo
Copy link
Contributor

AJenbo commented Mar 19, 2025

@amants the problem is that Larastan also needs to be updated: https://github.com/larastan/larastan/blob/3.x/stubs/common/BelongsToMany.stub maybe @calebdw can help with this?

The default suggested by @devfrey will probably serve to allow it to work with the older Larastan.

@calebdw
Copy link
Contributor

calebdw commented Mar 19, 2025

I had thought about something similar to enable the pivot property to work correctly: larastan/larastan#1774

However, the template should use a default to prevent every userland relationship from having to define it

@AJenbo
Copy link
Contributor

AJenbo commented Mar 19, 2025

I updated the stub in Larastan, I have tested that this indeed resolves the issue: larastan/larastan#2231

Having the default there is also enough to avoid having users needing to document it, but it should probably be made a default in both places.

@calebdw
Copy link
Contributor

calebdw commented Mar 19, 2025

I'm working on a PR for the framework right now to fix some things with this implementation

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

Successfully merging this pull request may close these issues.

7 participants