Skip to content

Commit

Permalink
fix: return type of associate, dissociate and getChild methods …
Browse files Browse the repository at this point in the history
…of `BelongsTo` relations (#633)
  • Loading branch information
canvural committed Aug 6, 2020
1 parent 63e362b commit a3038a7
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Fixed

- Return type of `associate`, `dissociate` and `getChild` methods of `BelongsTo` relations ([#633](https://github.com/nunomaduro/larastan/pull/633))

## [0.6.2] - 2020-07-30

### Fixed
Expand Down
10 changes: 10 additions & 0 deletions src/Types/ModelRelationsDynamicMethodReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace NunoMaduro\Larastan\Types;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Relation;
use NunoMaduro\Larastan\Concerns\HasContainer;
use PhpParser\Node\Expr\MethodCall;
Expand Down Expand Up @@ -93,6 +94,15 @@ public function getTypeFromMethodCall(
->relationParserHelper
->findRelatedModelInRelationMethod($methodReflection);

$classReflection = $methodReflection->getDeclaringClass();

if ($returnType->isInstanceOf(BelongsTo::class)->yes()) {
return new GenericObjectType($returnType->getClassName(), [
new ObjectType($relatedModelClassName),
new ObjectType($classReflection->getName()),
]);
}

return new GenericObjectType($returnType->getClassName(), [new ObjectType($relatedModelClassName)]);
}
}
9 changes: 8 additions & 1 deletion stubs/BelongsTo.stub
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ namespace Illuminate\Database\Eloquent\Relations;

/**
* @template TRelatedModel of \Illuminate\Database\Eloquent\Model
* @template TChildModel of \Illuminate\Database\Eloquent\Model
* @extends Relation<TRelatedModel>
*/
class BelongsTo extends Relation
{
/** @phpstan-return TRelatedModel */
/** @phpstan-return TChildModel */
public function associate();

/** @phpstan-return TChildModel */
public function dissociate();

/** @phpstan-return TChildModel */
public function getChild();

/**
* Get the results of the relationship.
*
Expand Down
19 changes: 16 additions & 3 deletions tests/Features/Models/Relations.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,15 @@ public function it_doesnt_treat_whereHas_as_dynamic_where(): User
}

/**
* @phpstan-return BelongsTo<User>
* @phpstan-return BelongsTo<User, Account>
*/
public function testRelationWithTrait(Account $account): BelongsTo
{
return $account->ownerRelation();
}

/**
* @phpstan-return BelongsTo<Account>
* @phpstan-return BelongsTo<Account, Account>
*/
public function testRelationInTraitWithStaticClass(Account $account): BelongsTo
{
Expand All @@ -156,7 +156,7 @@ public function testSameClassRelation(User $user): HasMany
return $user->children();
}

/** @phpstan-return BelongsTo<User> */
/** @phpstan-return BelongsTo<User, User> */
public function testSameClassRelationWithGetClass(User $user): BelongsTo
{
return $user->parent();
Expand Down Expand Up @@ -202,3 +202,16 @@ public function testRelationCreateOnExistingModel(): Account
return $this->user->accounts()->create();
}
}

class Post extends Model
{
public function author(): BelongsTo
{
return $this->belongsTo(User::class);
}

public function addUser(User $user): self
{
return $this->author()->associate($user);
}
}

0 comments on commit a3038a7

Please sign in to comment.