|
14 | 14 | namespace ApiPlatform\Laravel\Eloquent\State; |
15 | 15 |
|
16 | 16 | use ApiPlatform\Metadata\Exception\OperationNotFoundException; |
| 17 | +use ApiPlatform\Metadata\Exception\RuntimeException; |
17 | 18 | use ApiPlatform\Metadata\GraphQl\Operation; |
18 | 19 | use ApiPlatform\Metadata\GraphQl\Query; |
19 | 20 | use ApiPlatform\Metadata\HttpOperation; |
|
22 | 23 | use Illuminate\Contracts\Foundation\Application; |
23 | 24 | use Illuminate\Database\Eloquent\Builder; |
24 | 25 | use Illuminate\Database\Eloquent\Model; |
25 | | -use Illuminate\Database\Eloquent\Relations\MorphOneOrMany; |
| 26 | +use Illuminate\Database\Eloquent\Relations\BelongsTo; |
| 27 | +use Illuminate\Database\Eloquent\Relations\BelongsToMany; |
| 28 | +use Illuminate\Database\Eloquent\Relations\HasOneOrMany; |
| 29 | +use Illuminate\Database\Eloquent\Relations\MorphTo; |
| 30 | +use Illuminate\Database\Eloquent\Relations\Relation; |
26 | 31 |
|
27 | 32 | /** |
28 | 33 | * @implements LinksHandlerInterface<Model> |
@@ -102,41 +107,44 @@ private function buildQuery(Builder $builder, Link $link, mixed $identifier): Bu |
102 | 107 | } |
103 | 108 |
|
104 | 109 | if ($from = $link->getFromProperty()) { |
105 | | - $relation = $this->application->make($link->getFromClass()); |
106 | | - $relationQuery = $relation->{$from}(); |
| 110 | + /** @var Model $relatedInstance */ |
| 111 | + $relatedInstance = $this->application->make($link->getFromClass()); |
| 112 | + $relatedInstance->setAttribute($relatedInstance->getKeyName(), $identifier); |
| 113 | + $relatedInstance->exists = true; |
107 | 114 |
|
108 | | - if ($relationQuery instanceof MorphOneOrMany) { |
109 | | - return $builder |
110 | | - ->where($relationQuery->getForeignKeyName(), $identifier) |
111 | | - ->where($relationQuery->getMorphType(), $relationQuery->getMorphClass()); |
| 115 | + /** @var Relation<Model, Model, mixed> $relation */ |
| 116 | + $relation = $relatedInstance->{$from}(); |
| 117 | + |
| 118 | + if ($relation instanceof MorphTo) { |
| 119 | + throw new RuntimeException('Cannot query directly from a MorphTo relationship.'); |
112 | 120 | } |
113 | 121 |
|
114 | | - if (!method_exists($relationQuery, 'getQualifiedForeignKeyName') && method_exists($relationQuery, 'getQualifiedForeignPivotKeyName')) { |
| 122 | + if ($relation instanceof BelongsTo) { |
115 | 123 | return $builder->getModel() |
116 | 124 | ->join( |
117 | | - $relationQuery->getTable(), // @phpstan-ignore-line |
118 | | - $relationQuery->getQualifiedRelatedPivotKeyName(), // @phpstan-ignore-line |
119 | | - $builder->getModel()->getQualifiedKeyName() |
120 | | - ) |
121 | | - ->where( |
122 | | - $relationQuery->getQualifiedForeignPivotKeyName(), // @phpstan-ignore-line |
| 125 | + $relation->getParent()->getTable(), |
| 126 | + $relation->getParent()->getQualifiedKeyName(), |
123 | 127 | $identifier |
124 | | - ) |
125 | | - ->select($builder->getModel()->getTable().'.*'); |
| 128 | + ); |
126 | 129 | } |
127 | 130 |
|
128 | | - if (method_exists($relationQuery, 'dissociate')) { |
129 | | - return $builder->getModel() |
130 | | - ->join( |
131 | | - $relationQuery->getParent()->getTable(), // @phpstan-ignore-line |
132 | | - $relationQuery->getParent()->getQualifiedKeyName(), // @phpstan-ignore-line |
133 | | - $identifier |
134 | | - ); |
| 131 | + if ($relation instanceof HasOneOrMany || $relation instanceof BelongsToMany) { |
| 132 | + return $relation->getQuery(); |
| 133 | + } |
| 134 | + |
| 135 | + if (method_exists($relation, 'getQualifiedForeignKeyName')) { |
| 136 | + return $relation->getQuery()->where( |
| 137 | + $relation->getQualifiedForeignKeyName(), |
| 138 | + $identifier |
| 139 | + ); |
135 | 140 | } |
136 | 141 |
|
137 | | - return $builder->getModel()->where($relationQuery->getQualifiedForeignKeyName(), $identifier); |
| 142 | + throw new RuntimeException(\sprintf('Unhandled or unknown relationship type: %s for property %s on %s', $relation::class, $from, $relatedInstance::class)); |
138 | 143 | } |
139 | 144 |
|
140 | | - return $builder->where($builder->getModel()->qualifyColumn($link->getIdentifiers()[0]), $identifier); |
| 145 | + return $builder->where( |
| 146 | + $builder->getModel()->qualifyColumn($link->getIdentifiers()[0]), |
| 147 | + $identifier |
| 148 | + ); |
141 | 149 | } |
142 | 150 | } |
0 commit comments