Skip to content

Commit 6115100

Browse files
authored
Add support for composite keys (#1479)
* Add support for composite keys * chore: add composite foreign key test
1 parent 5c886fb commit 6115100

File tree

6 files changed

+117
-5
lines changed

6 files changed

+117
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
1414
### Added
1515
- Add support for enum default arguments using enum cases. [#1464 / d8vjork](https://github.com/barryvdh/laravel-ide-helper/pull/1464)
1616
- Add support for real-time facades in the helper file. [#1455 / filipac](https://github.com/barryvdh/laravel-ide-helper/pull/1455)
17+
- Add support for relations with composite keys. [#1479 / calebdw](https://github.com/barryvdh/laravel-ide-helper/pull/1479)
1718

1819
2024-02-05, 2.14.0
1920
------------------

config/ide-helper.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@
322322
|
323323
| When using custom relation types its possible for the class name to not contain
324324
| the proper return type of the relation. The key of the array is the relationship
325-
| method name. The value of the array is the return type of the relation.
325+
| method name. The value of the array is the return type of the relation ('many'
326+
| or 'morphTo').
326327
| e.g. `'relationName' => 'many'`.
327328
|
328329
*/

src/Console/ModelsCommand.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use Illuminate\Database\Eloquent\Relations\MorphToMany;
3939
use Illuminate\Database\Eloquent\Relations\Relation;
4040
use Illuminate\Filesystem\Filesystem;
41+
use Illuminate\Support\Arr;
4142
use Illuminate\Support\Collection;
4243
use Illuminate\Support\Str;
4344
use phpDocumentor\Reflection\Types\ContextFactory;
@@ -843,12 +844,17 @@ protected function isRelationNullable(string $relation, Relation $relationObj):
843844
$fkProp = $reflectionObj->getProperty('foreignKey');
844845
$fkProp->setAccessible(true);
845846

846-
if ($relation === 'belongsTo') {
847-
return isset($this->nullableColumns[$fkProp->getValue($relationObj)]) ||
848-
!in_array($fkProp->getValue($relationObj), $this->foreignKeyConstraintsColumns, true);
847+
foreach (Arr::wrap($fkProp->getValue($relationObj)) as $foreignKey) {
848+
if (isset($this->nullableColumns[$foreignKey])) {
849+
return true;
850+
}
851+
852+
if (!in_array($foreignKey, $this->foreignKeyConstraintsColumns, true)) {
853+
return true;
854+
}
849855
}
850856

851-
return isset($this->nullableColumns[$fkProp->getValue($relationObj)]);
857+
return false;
852858
}
853859

854860
/**
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models;
6+
7+
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9+
10+
class CompositeBelongsToVariation extends Model
11+
{
12+
public $table = 'belongs_to_variations';
13+
14+
public function bothNonNullableWithForeignKeyConstraint(): BelongsTo
15+
{
16+
// Note, duplicating the keys here for simplicity.
17+
return $this->belongsTo(
18+
self::class,
19+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
20+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
21+
);
22+
}
23+
24+
public function nonNullableMixedWithoutForeignKeyConstraint(): BelongsTo
25+
{
26+
return $this->belongsTo(
27+
self::class,
28+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_no_foreign_key_constraint'],
29+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_no_foreign_key_constraint'],
30+
);
31+
}
32+
33+
public function nullableMixedWithForeignKeyConstraint(): BelongsTo
34+
{
35+
return $this->belongsTo(
36+
self::class,
37+
['nullable_column_with_no_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
38+
['nullable_column_with_no_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
39+
);
40+
}
41+
}

tests/Console/ModelsCommand/Relations/Test.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
88
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
9+
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyMorphedRelationType;
910
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToAnyRelationType;
1011
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToManyRelationType;
1112
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Types\SampleToOneRelationType;

tests/Console/ModelsCommand/Relations/__snapshots__/Test__test__1.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,68 @@ public function nullableColumnWithNoForeignKeyConstraint(): BelongsTo
5757

5858
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models;
5959

60+
use Illuminate\Database\Eloquent\Model;
61+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
62+
63+
/**
64+
* Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\CompositeBelongsToVariation
65+
*
66+
* @property integer $id
67+
* @property integer $not_null_column_with_foreign_key_constraint
68+
* @property integer $not_null_column_with_no_foreign_key_constraint
69+
* @property integer|null $nullable_column_with_foreign_key_constraint
70+
* @property integer|null $nullable_column_with_no_foreign_key_constraint
71+
* @property-read CompositeBelongsToVariation $bothNonNullableWithForeignKeyConstraint
72+
* @property-read CompositeBelongsToVariation|null $nonNullableMixedWithoutForeignKeyConstraint
73+
* @property-read CompositeBelongsToVariation|null $nullableMixedWithForeignKeyConstraint
74+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation newModelQuery()
75+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation newQuery()
76+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation query()
77+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation whereId($value)
78+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation whereNotNullColumnWithForeignKeyConstraint($value)
79+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation whereNotNullColumnWithNoForeignKeyConstraint($value)
80+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation whereNullableColumnWithForeignKeyConstraint($value)
81+
* @method static \Illuminate\Database\Eloquent\Builder|CompositeBelongsToVariation whereNullableColumnWithNoForeignKeyConstraint($value)
82+
* @mixin \Eloquent
83+
*/
84+
class CompositeBelongsToVariation extends Model
85+
{
86+
public $table = 'belongs_to_variations';
87+
88+
public function bothNonNullableWithForeignKeyConstraint(): BelongsTo
89+
{
90+
// Note, duplicating the keys here for simplicity.
91+
return $this->belongsTo(
92+
self::class,
93+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
94+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
95+
);
96+
}
97+
98+
public function nonNullableMixedWithoutForeignKeyConstraint(): BelongsTo
99+
{
100+
return $this->belongsTo(
101+
self::class,
102+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_no_foreign_key_constraint'],
103+
['not_null_column_with_foreign_key_constraint', 'not_null_column_with_no_foreign_key_constraint'],
104+
);
105+
}
106+
107+
public function nullableMixedWithForeignKeyConstraint(): BelongsTo
108+
{
109+
return $this->belongsTo(
110+
self::class,
111+
['nullable_column_with_no_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
112+
['nullable_column_with_no_foreign_key_constraint', 'not_null_column_with_foreign_key_constraint'],
113+
);
114+
}
115+
}
116+
<?php
117+
118+
declare(strict_types=1);
119+
120+
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models;
121+
60122
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\ModelsOtherNamespace\AnotherModel;
61123
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Traits\HasTestRelations;
62124
use Illuminate\Database\Eloquent\Model;

0 commit comments

Comments
 (0)