Skip to content

Commit 4c2873f

Browse files
authored
Output related models when available in resources (#495)
1 parent 118125e commit 4c2873f

File tree

4 files changed

+107
-8
lines changed

4 files changed

+107
-8
lines changed

src/Generators/Statements/ResourceGenerator.php

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Blueprint\Models\Statements\ResourceStatement;
1010
use Blueprint\Tree;
1111
use Illuminate\Filesystem\Filesystem;
12+
use Illuminate\Support\Arr;
1213
use Illuminate\Support\Str;
1314

1415
class ResourceGenerator implements Generator
@@ -39,12 +40,12 @@ public function output(Tree $tree): array
3940
$stub = $this->filesystem->stub('resource.stub');
4041

4142
/**
42-
* @var \Blueprint\Models\Controller $controller
43-
*/
43+
* @var \Blueprint\Models\Controller $controller
44+
*/
4445
foreach ($tree->controllers() as $controller) {
4546
foreach ($controller->methods() as $method => $statements) {
4647
foreach ($statements as $statement) {
47-
if (! $statement instanceof ResourceStatement) {
48+
if (!$statement instanceof ResourceStatement) {
4849
continue;
4950
}
5051

@@ -54,7 +55,7 @@ public function output(Tree $tree): array
5455
continue;
5556
}
5657

57-
if (! $this->filesystem->exists(dirname($path))) {
58+
if (!$this->filesystem->exists(dirname($path))) {
5859
$this->filesystem->makeDirectory(dirname($path), 0755, true);
5960
}
6061

@@ -103,8 +104,8 @@ protected function buildData(ResourceStatement $resource)
103104
$context = Str::singular($resource->reference());
104105

105106
/**
106-
* @var \Blueprint\Models\Model $model
107-
*/
107+
* @var \Blueprint\Models\Model $model
108+
*/
108109
$model = $this->tree->modelForContext($context);
109110

110111
$data = [];
@@ -120,6 +121,26 @@ protected function buildData(ResourceStatement $resource)
120121
foreach ($this->visibleColumns($model) as $column) {
121122
$data[] = self::INDENT . '\'' . $column . '\' => $this->' . $column . ',';
122123
}
124+
125+
foreach ($model->relationships() as $type => $relationship) {
126+
$method_name = lcfirst(Str::afterLast(Arr::last($relationship), '\\'));
127+
128+
$relation_model = $this->tree->modelForContext($method_name);
129+
130+
if ($relation_model === null) {
131+
continue;
132+
}
133+
134+
if (in_array($type, ['hasMany', 'belongsToMany', 'morphMany'])) {
135+
$relation_resource_name = $relation_model->name() . 'Collection';
136+
$method_name = Str::plural($method_name);
137+
} else {
138+
$relation_resource_name = $relation_model->name() . 'Resource';
139+
}
140+
141+
$data[] = self::INDENT . '\'' . $method_name . '\' => ' . $relation_resource_name . '::make($this->whenLoaded(\'' . $method_name . '\')),';
142+
}
143+
123144
$data[] = ' ];';
124145

125146
return implode(PHP_EOL, $data);
@@ -130,8 +151,8 @@ private function visibleColumns(Model $model)
130151
return array_diff(
131152
array_keys($model->columns()),
132153
[
133-
'password',
134-
'remember_token',
154+
'password',
155+
'remember_token',
135156
]
136157
);
137158
}

tests/Feature/Generators/Statements/ResourceGeneratorTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,42 @@ public function output_writes_namespaced_classes()
136136
], $this->subject->output($tree));
137137
}
138138

139+
/**
140+
* @test
141+
*/
142+
public function output_writes_nested_resource()
143+
{
144+
$this->filesystem->expects('stub')
145+
->with('resource.stub')
146+
->andReturn(file_get_contents('stubs/resource.stub'));
147+
148+
$this->filesystem->shouldReceive('exists')
149+
->with('app/Http/Resources/Api')
150+
->andReturns(false, true);
151+
$this->filesystem->expects('makeDirectory')
152+
->with('app/Http/Resources/Api', 0755, true);
153+
154+
$this->filesystem->expects('exists')
155+
->times(3)
156+
->with('app/Http/Resources/Api/CertificateResource.php')
157+
->andReturns(false, true, true);
158+
$this->filesystem->expects('put')
159+
->with('app/Http/Resources/Api/CertificateResource.php', $this->fixture('resources/certificate-with-nested-resource.php'));
160+
161+
$this->filesystem->expects('exists')
162+
->with('app/Http/Resources/Api/CertificateCollection.php')
163+
->andReturns(false);
164+
$this->filesystem->expects('put')
165+
->with('app/Http/Resources/Api/CertificateCollection.php', $this->fixture('resources/certificate-collection.php'));
166+
167+
$tokens = $this->blueprint->parse($this->fixture('drafts/resource-nested.yaml'));
168+
$tree = $this->blueprint->analyze($tokens);
169+
170+
$this->assertEquals([
171+
'created' => ['app/Http/Resources/Api/CertificateCollection.php', 'app/Http/Resources/Api/CertificateResource.php'],
172+
], $this->subject->output($tree));
173+
}
174+
139175
/**
140176
* @test
141177
*/
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
models:
2+
Certificate:
3+
name: string
4+
reference: string
5+
document: string
6+
expiry_date: date
7+
remarks: text nullable
8+
relationships:
9+
belongsTo: \App\Certificate
10+
hasMany: \App\Certificate
11+
12+
controllers:
13+
Api/Certificate:
14+
resource: api
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace App\Http\Resources\Api;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
7+
class CertificateResource extends JsonResource
8+
{
9+
/**
10+
* Transform the resource into an array.
11+
*
12+
* @param \Illuminate\Http\Request $request
13+
* @return array
14+
*/
15+
public function toArray($request)
16+
{
17+
return [
18+
'id' => $this->id,
19+
'name' => $this->name,
20+
'reference' => $this->reference,
21+
'document' => $this->document,
22+
'expiry_date' => $this->expiry_date,
23+
'remarks' => $this->remarks,
24+
'certificate' => CertificateResource::make($this->whenLoaded('certificate')),
25+
'certificates' => CertificateCollection::make($this->whenLoaded('certificates')),
26+
];
27+
}
28+
}

0 commit comments

Comments
 (0)