-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[11.x] feat: add generics to Eloquent Builder and Relations #51851
Conversation
6a0123b
to
90b5bd0
Compare
I've been waiting for this for a long time! This is a must-have if you want to run larastan (phpstan) on level 7 or above and have re-usable scopes in a Trait for example... Currently there's no way to use scopes from a Trait (eg. morphable logic) and type them as |
Hey @calebdw - thanks for looking into this. What made you send it to |
@taylorotwell, sure thing! I targeted Note that I also created a For example: // before
class Post extends Model
{
/** @return CommonBuilder<static> */
public static function query(): CommonBuilder
{
return parent::query();
}
/**
* @param \Illuminate\Database\Query\Builder $query
* @return CommonBuilder<*>
*/
public function newEloquentBuilder($query): CommonBuilder
{
return new CommonBuilder($query);
}
}
// after
class Post extends Model
{
/** @use HasBuilder<CommonBuilder<static>> */
use HasBuilder;
protected static string $builder = CommonBuilder::class;
} However, if this is not desired then I can just pop the |
Let's just target this to 11.x. |
129b0b2
to
35a5bf4
Compare
35a5bf4
to
e31e1ce
Compare
@taylorotwell, yes sir---done! |
Co-authored-by: Jonas Staudenmeir <mail@jonas-staudenmeir.de>
0a3f29e
to
22e2b14
Compare
22e2b14
to
76a3a0d
Compare
We will need to wait for @nunomaduro to take a look at this. Would appreciate other community feedback in the meantime. |
Just ran this on one of our web apps to check if it works, and it seems to work fine, reporting a few additional things that were statically ambiguous. Was hoping this change might actually help in solving larastan/larastan#1538, but so far it didn't, but maybe that's because there's still some stubs from Larastan taking precedence over changes here? If so, there's probably a parallel MR required to remove those parts of the stubs there that might otherwise conflict with things in here? |
@jnoordsij, yes changes to Larastan will be needed which I plan on implementing |
Thanks for your work on this! |
Thank you! |
Thanks @calebdw 👍 |
@calebdw thanks 🚀 I can improve and remove useless |
but not everything works correctly, for example: my fault, I read and found your another pr for doing this: #51681 |
@siarheipashkevich, it's always good to remove overrides! If you're using Larastan then I'm working on a PR (larastan/larastan#1990) to add support for the new generics. If you're not using Larastan then there are some limitations (particularly when you start getting into method forwarding) that can't be solved with PHPDocs alone. However, I have tests for your particular example so the issue is likely in your relation phpdocs
|
thats what we have been waiting for long time |
This should be reverted when the issues with Laravel 11 is resolved
@decadence This kind of seems like a PHPStorm Problem, because it tries to search |
Hello!
I've been contributing a bunch to Larastan, and have been wanting to integrate the relation generics into the framework for a while now. Generics provide better auto-completion and intellisense in the ide without having to rely on Larastan to add generics to the classes through the use of stubs. Having generics in the framework also makes it easier for third party packages to define the inner types on their custom relations.
There is another PR (#51681) open to add generics to Relations, but this offers a more complete and better tested implementation. I've gone ahead and implemented @nagmat84's fixes and notation from his PR (larastan/larastan#1285) to fix the Larastan stubs. Please see that PR for an extensive write up on the rationale behind the changes.
Examples:
New
HasOneOrManyThrough
RelationI created an abstract
HasOneOrManyThrough
class that theHasOneThrough
/HasManyThrough
classes extend (similar to the other OneOrMany abstract classes). This was necessary to allow theHasManyThrough
class to properly bind theTResult
generic to a collection instead of leaving it unbound forHasOneThrough
class to bind to a Model.HasBuilder
TraitI created a
HasBuilder
trait that reduces boilerplate when using custom Builders---while they are not for everyone, custom Builders do work better with static analysis / auto-completion over scopes and they help slim down the models. The trait helps IDEs better resolve the correct classes when they are used.For example:
Thanks!