Skip to content

Commit 0c28a69

Browse files
committed
Generate belongs to relationhships for models
1 parent 8d51c72 commit 0c28a69

File tree

10 files changed

+134
-8
lines changed

10 files changed

+134
-8
lines changed

src/Generators/MigrationGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ protected function buildDefinition(Model $model)
6262

6363
$definition .= self::INDENT . '$table->' . $dataType . "('{$column->name()}'";
6464

65-
if (!empty($column->attributes())) {
65+
if (!empty($column->attributes()) && $column->dataType() !== 'id') {
6666
$definition .= ', ';
6767
if (in_array($column->dataType(), ['set', 'enum'])) {
6868
$definition .= json_encode($column->attributes());

src/Generators/ModelGenerator.php

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Blueprint\Contracts\Generator;
66
use Blueprint\Models\Column;
77
use Blueprint\Models\Model;
8+
use Illuminate\Support\Str;
89

910
class ModelGenerator implements Generator
1011
{
@@ -40,7 +41,12 @@ protected function populateStub(string $stub, Model $model)
4041
{
4142
$stub = str_replace('DummyNamespace', 'App', $stub);
4243
$stub = str_replace('DummyClass', $model->name(), $stub);
43-
$stub = str_replace('// properties...', $this->buildProperties($model), $stub);
44+
45+
$body = $this->buildProperties($model);
46+
$body .= PHP_EOL . PHP_EOL;
47+
$body .= $this->buildRelationships($model);
48+
49+
$stub = str_replace('// ...', trim($body), $stub);
4450
$stub = $this->addTraits($model, $stub);
4551

4652
return $stub;
@@ -52,24 +58,52 @@ private function buildProperties(Model $model)
5258

5359
$columns = $this->fillableColumns($model->columns());
5460
if (!empty($columns)) {
55-
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns, false), $this->propertyStub('fillable'));
61+
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns, false), $this->getStub('fillable'));
5662
} else {
57-
$properties .= $this->propertyStub('fillable');
63+
$properties .= $this->getStub('fillable');
5864
}
5965

6066
$columns = $this->castableColumns($model->columns());
6167
if (!empty($columns)) {
62-
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns), $this->propertyStub('casts'));
68+
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns), $this->getStub('casts'));
6369
}
6470

6571
$columns = $this->dateColumns($model->columns());
6672
if (!empty($columns)) {
67-
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns, false), $this->propertyStub('dates'));
73+
$properties .= PHP_EOL . str_replace('[]', $this->pretty_print_array($columns, false), $this->getStub('dates'));
6874
}
6975

7076
return trim($properties);
7177
}
7278

79+
private function buildRelationships(Model $model)
80+
{
81+
$columns = array_filter($model->columns(), function (Column $column) {
82+
return Str::endsWith($column->name(), '_id');
83+
});
84+
85+
if (empty($columns)) {
86+
return '';
87+
}
88+
89+
$methods = '';
90+
$template = $this->getStub('method');
91+
92+
/** @var Column $column */
93+
foreach ($columns as $column) {
94+
$name = Str::substr($column->name(), 0, -3);
95+
$class = Str::studly($column->attributes()[0] ?? $name);
96+
$relationship = sprintf("\$this->belongsTo(\App\%s::class)", $class);
97+
98+
$method = str_replace('DummyName', Str::camel($name), $template);
99+
$method = str_replace('null', $relationship, $method);
100+
101+
$methods .= PHP_EOL . $method;
102+
}
103+
104+
return $methods;
105+
}
106+
73107
protected function getPath(Model $model)
74108
{
75109
return 'app/' . $model->name() . '.php';
@@ -140,7 +174,7 @@ private function pretty_print_array(array $data, $assoc = true)
140174
return trim($output);
141175
}
142176

143-
private function propertyStub(string $stub)
177+
private function getStub(string $stub)
144178
{
145179
static $stubs = [];
146180

src/Lexers/ModelLexer.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ private function buildColumn(string $name, string $definition)
147147

148148
if ($value === 'id') {
149149
$data_type = 'id';
150+
if (isset($parts[1])) {
151+
$attributes = [$parts[1]];
152+
}
150153
} elseif (isset(self::$dataTypes[strtolower($value)])) {
151154
$attributes = $parts[1] ?? null;
152155
$data_type = self::$dataTypes[strtolower($value)];

stubs/model/class.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ use Illuminate\Database\Eloquent\Model;
66

77
class DummyClass extends Model
88
{
9-
// properties...
9+
// ...
1010
}

stubs/model/method.stub

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public function DummyName()
2+
{
3+
return null;
4+
}

tests/Feature/Generator/MigrationGeneratorTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public function modelTreeDataProvider()
7777
['definitions/model-modifiers.bp', 'database/migrations/timestamp_create_modifiers_table.php', 'migrations/modifiers.php'],
7878
['definitions/soft-deletes.bp', 'database/migrations/timestamp_create_comments_table.php', 'migrations/soft-deletes.php'],
7979
['definitions/with-timezones.bp', 'database/migrations/timestamp_create_comments_table.php', 'migrations/with-timezones.php'],
80+
['definitions/relationships.bp', 'database/migrations/timestamp_create_comments_table.php', 'migrations/relationships.php'],
8081
];
8182
}
8283
}

tests/Feature/Generator/ModelGeneratorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ public function output_writes_migration_for_model_tree($definition, $path, $mode
6767
->andReturn(file_get_contents('stubs/model/dates.stub'));
6868
}
6969

70+
if ($definition === 'definitions/relationships.bp') {
71+
$this->files->expects('get')
72+
->with('stubs/model/method.stub')
73+
->andReturn(file_get_contents('stubs/model/method.stub'));
74+
}
75+
7076
$this->files->expects('put')
7177
->with($path, $this->fixture($model));
7278

@@ -84,6 +90,7 @@ public function modelTreeDataProvider()
8490
['definitions/readme-example.bp', 'app/Post.php', 'models/readme-example.php'],
8591
['definitions/soft-deletes.bp', 'app/Comment.php', 'models/soft-deletes.php'],
8692
['definitions/with-timezones.bp', 'app/Comment.php', 'models/soft-deletes.php'],
93+
['definitions/relationships.bp', 'app/Comment.php', 'models/relationships.php'],
8794
];
8895
}
8996
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
models:
2+
Comment:
3+
post_id: id
4+
author_id: id:user
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class CreateCommentsTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('comments', function (Blueprint $table) {
17+
$table->increments('id');
18+
$table->unsignedBigInteger('post_id');
19+
$table->unsignedBigInteger('author_id');
20+
$table->timestamps();
21+
});
22+
}
23+
24+
/**
25+
* Reverse the migrations.
26+
*
27+
* @return void
28+
*/
29+
public function down()
30+
{
31+
Schema::dropIfExists('comments');
32+
}
33+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Comment extends Model
8+
{
9+
/**
10+
* The attributes that are mass assignable.
11+
*
12+
* @var array
13+
*/
14+
protected $fillable = [
15+
'post_id',
16+
'author_id',
17+
];
18+
19+
/**
20+
* The attributes that should be cast to native types.
21+
*
22+
* @var array
23+
*/
24+
protected $casts = [
25+
'id' => 'integer',
26+
'post_id' => 'integer',
27+
'author_id' => 'integer',
28+
];
29+
30+
31+
public function post()
32+
{
33+
return $this->belongsTo(\App\Post::class);
34+
}
35+
36+
public function author()
37+
{
38+
return $this->belongsTo(\App\User::class);
39+
}
40+
}

0 commit comments

Comments
 (0)