Skip to content

Commit 5ddcda4

Browse files
committed
🐛 include distant relation problem
1 parent 0c73df6 commit 5ddcda4

File tree

7 files changed

+65
-8
lines changed

7 files changed

+65
-8
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Here is a quick look at what you can do using API search method:
6969
"type": "max",
7070
"field": "rate",
7171
"filters": [
72-
{"field": 'approved', "value": true}
72+
{"field": "approved', "value": true}
7373
]
7474
},
7575
],

src/Console/stubs/resource.stub

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class {{ class }} extends Resource
2929
return [];
3030
}
3131

32-
public function exposedPaginations(\Lomkit\Rest\Http\Requests\RestRequest $request) {
32+
public function exposedLimits(\Lomkit\Rest\Http\Requests\RestRequest $request) {
3333
return [
3434
10,
3535
25,

src/Console/stubs/user-resource.stub

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class User extends Resource
3131
return [];
3232
}
3333

34-
public function exposedPaginations(\Lomkit\Rest\Http\Requests\RestRequest $request) {
34+
public function exposedLimits(\Lomkit\Rest\Http\Requests\RestRequest $request) {
3535
return [
3636
10,
3737
25,

src/Http/Response.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ protected function buildGatesForModel(Model $model) {
4141
}
4242

4343
public function modelToResponse(Model $model, Resource $resource, array $requestArray, Relation $relation = null) {
44+
$currentRequestArray = $relation === null ? $requestArray : collect($requestArray['includes'])
45+
->first(function ($include) use ($relation) {
46+
return preg_match('/(?:\.\b)?'.$relation->relation.'\b/', $include['relation']);
47+
});
48+
4449
return array_merge(
4550
// toArray to take advantage of Laravel's logic
4651
collect($model->attributesToArray())
@@ -84,7 +89,7 @@ public function modelToResponse(Model $model, Resource $resource, array $request
8489
$relationResource = $relationConcrete->resource();
8590
$requestArrayRelation = collect($requestArray['includes'])
8691
->first(function ($include) use ($relationName) {
87-
return $include['relation'] === $relationName;
92+
return preg_match('/(?:\.\b)?'.$relationName.'\b/', $include['relation']);
8893
});
8994

9095
// We reapply the limits in case of BelongsToManyRelation where we can't apply limits easily
@@ -95,14 +100,14 @@ public function modelToResponse(Model $model, Resource $resource, array $request
95100
$key => $this->modelToResponse(
96101
$modelRelation,
97102
$relationResource,
98-
$requestArrayRelation,
103+
$requestArray,
99104
$relationConcrete
100105
)
101106
];
102107
}
103108
return [
104109
$key => $modelRelation
105-
->map(fn ($collectionRelation) => $this->modelToResponse($collectionRelation, $relationResource, $requestArrayRelation, $relationConcrete))
110+
->map(fn ($collectionRelation) => $this->modelToResponse($collectionRelation, $relationResource, $requestArray, $relationConcrete))
106111
->toArray()
107112
];
108113
})

tests/Feature/Controllers/SearchIncludingRelationshipsOperationsTest.php

+49
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,55 @@ public function test_getting_a_list_of_resources_including_belongs_to_relation()
8484
);
8585
}
8686

87+
public function test_getting_a_list_of_resources_including_belongs_to_has_many_relation(): void
88+
{
89+
$belongsTo = BelongsToRelationFactory::new()->create();
90+
$matchingModel = ModelFactory::new()
91+
->for($belongsTo)
92+
->create()->fresh();
93+
94+
$matchingModel2 = ModelFactory::new()->create()->fresh();
95+
96+
Gate::policy(Model::class, GreenPolicy::class);
97+
Gate::policy(BelongsToRelation::class, GreenPolicy::class);
98+
99+
$response = $this->post(
100+
'/api/models/search',
101+
[
102+
'includes' => [
103+
['relation' => 'belongsToRelation.models'],
104+
],
105+
],
106+
['Accept' => 'application/json']
107+
);
108+
109+
$matchingModelBelongsToRelation = $matchingModel->belongsToRelation;
110+
111+
$this->assertResourcePaginated(
112+
$response,
113+
[$matchingModel, $matchingModel2],
114+
new ModelResource,
115+
[
116+
[
117+
'belongs_to_relation' => array_merge(
118+
$matchingModelBelongsToRelation
119+
->only((new BelongsToResource)->exposedFields(app()->make(RestRequest::class))),
120+
[
121+
'models' => $matchingModelBelongsToRelation->models
122+
->map(function($model) {
123+
return $model->only((new ModelResource)->exposedFields(app()->make(RestRequest::class)));
124+
})
125+
->toArray(),
126+
]
127+
),
128+
],
129+
[
130+
'belongs_to_relation' => null,
131+
]
132+
]
133+
);
134+
}
135+
87136
public function test_getting_a_list_of_resources_including_has_one_relation(): void
88137
{
89138
$matchingModel = ModelFactory::new()

tests/Support/Models/BelongsToRelation.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
class BelongsToRelation extends BaseModel
88
{
9-
public function model() {
9+
public function models() {
1010
return $this->hasMany(Model::class);
1111
}
1212
}

tests/Support/Rest/Resources/BelongsToResource.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Lomkit\Rest\Concerns\Resource\DisableAutomaticGates;
77
use Lomkit\Rest\Http\Requests\RestRequest;
88
use Lomkit\Rest\Http\Resource;
9+
use Lomkit\Rest\Relations\HasMany;
910
use Lomkit\Rest\Tests\Support\Models\BelongsToRelation;
1011

1112
class BelongsToResource extends Resource
@@ -16,7 +17,9 @@ class BelongsToResource extends Resource
1617

1718
public function relations(RestRequest $request)
1819
{
19-
return [];
20+
return [
21+
HasMany::make('models', ModelResource::class)
22+
];
2023
}
2124

2225
public function exposedFields(RestRequest $request)

0 commit comments

Comments
 (0)