- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 440
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
Custom builder for relation methods #409
Comments
Very nice bug report. |
Hi, Thanks for the report! The error you got is a little weird. It thinks If you want to fix this you can do it in You should check the return type of You should also check the magic |
Hey, Thanks for the reply! The error is definitely weird, but makes sense reading the ModelScopeAfterRelations file. I will try to fix it once I have some spare time! A more complete example: <?php
declare(strict_types=1);
namespace Tests\Unit;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Tests\TestCase;
class User extends Model
{
public function topics(): HasMany
{
return $this->hasMany(Topic::class);
}
}
class Topic extends Model
{
public function newEloquentBuilder($query): TopicBuilder
{
return new TopicBuilder($query);
}
}
class TopicBuilder extends Builder
{
public function category(string $category): self
{
return $this->where('category', $category);
}
}
class LaraStanTest extends TestCase
{
public function test_larastan(): void
{
$user = new User();
$user->topics()->category('Foo')->get();
}
} Results in:
|
Hmm, when looking into it, it seems like If I change public function testScopeAfterRelation() : HasOne
{
return $this->hasOne(User::class)->active('THIS_IS_DIFFERENT');
} And the active scope to: public function scopeActive(Builder $query, string $newParam): Builder
{
return $query->where('active', 1);
} I get a similar error as mentioned above Expected I tried to get access to the User class from within |
It's because of this line This needs to be changed.
Yeah, you are right. I guess there is no way to get the model here. Maybe I can solve this later. But I think we still have some issues like calling the query builder methods on the relation. For example |
Let me know if I can be of some help testing something in a live project. As for returning the query builder when using |
It's the same file. We should mimic the magic Then you should get the method reflection for that, and check the return type. If it includes any if ($result === $this->query) {
return $this;
}
return $result; |
Hi, Can you test this again against the |
Hi @canvural, I have tested it in my project. It's not complaining anymore but it's also not checking types or argument count so it gives false positives which is in my opinion worse then the errors it gave. Example: <?php
declare(strict_types=1);
namespace Tests\Unit;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Tests\TestCase;
class User extends Model
{
public function topics(): HasMany
{
return $this->hasMany(Topic::class);
}
}
class Topic extends Model
{
public function newEloquentBuilder($query): TopicBuilder
{
return new TopicBuilder($query);
}
}
class TopicBuilder extends Builder
{
public function category(string $category): self
{
return $this->where('category', $category);
}
}
class LaraStanTest extends TestCase
{
public function test_larastan(): void
{
$user = new User();
$user->topics()->category(1, false)->get();
}
} |
Ok, thank you for testing again! I'll look into the custom builder support! |
--level
used: 5Description
Calling custom builder methods on a relationship works in Laravel but larastan shows the following error:
Method Illuminate\Database\Eloquent\Model::uncategorized() invoked with 1 parameters, 0 required.
.Laravel code where the issue was found for example:
I would love to contribute but I have no idea where to start.
My idea is that whenever a
Relation
class is returned from a function it should check the class given in the relationship for a custom builder and return anIntersectionType
of the relations class (e.g.HasMany
) and the custom builder.Changing the test
EloquentBuilderExtension
to the following should test it I believe.The text was updated successfully, but these errors were encountered: