From 52a4b64656d3d833d6eef5f33785c64aebd7ae51 Mon Sep 17 00:00:00 2001 From: "atsu.kg" Date: Sat, 7 Aug 2021 20:31:20 +0900 Subject: [PATCH] Consider foreign key constraints with isRelationNullable (#1231) * Consider foreign key constraints with isRelationNullable * test: add belongsTo Variation * command: composer test-regenerate --- src/Console/ModelsCommand.php | 24 ++++++++ .../Relations/Models/BelongsToVariation.php | 31 ++++++++++ .../Relations/__snapshots__/Test__test__1.php | 59 ++++++++++++++++++- .../____belongs_to_variation_table.php | 23 ++++++++ 4 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 tests/Console/ModelsCommand/Relations/Models/BelongsToVariation.php create mode 100644 tests/Console/ModelsCommand/migrations/____belongs_to_variation_table.php diff --git a/src/Console/ModelsCommand.php b/src/Console/ModelsCommand.php index c117310..5ad82b8 100644 --- a/src/Console/ModelsCommand.php +++ b/src/Console/ModelsCommand.php @@ -102,6 +102,10 @@ class ModelsCommand extends Command * @var bool[string] */ protected $nullableColumns = []; + /** + * @var string[] + */ + protected $foreignKeyConstraintsColumns = []; /** * During initialization we use Laravels Date Facade to @@ -452,6 +456,7 @@ class ModelsCommand extends Command return; } + $this->setForeignKeys($schema, $table); foreach ($columns as $column) { $name = $column->getName(); if (in_array($name, $model->getDates())) { @@ -726,6 +731,11 @@ class ModelsCommand extends Command $fkProp = $reflectionObj->getProperty('foreignKey'); $fkProp->setAccessible(true); + if ($relation === 'belongsTo') { + return isset($this->nullableColumns[$fkProp->getValue($relationObj)]) || + !in_array($fkProp->getValue($relationObj), $this->foreignKeyConstraintsColumns, true); + } + return isset($this->nullableColumns[$fkProp->getValue($relationObj)]); } @@ -1409,4 +1419,18 @@ class ModelsCommand extends Command $hookInstance->run($this, $model); } } + + /** + * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema + * @param string $table + * @throws DBALException + */ + protected function setForeignKeys($schema, $table) + { + foreach ($schema->listTableForeignKeys($table) as $foreignKeyConstraint) { + foreach ($foreignKeyConstraint->getLocalColumns() as $columnName) { + $this->foreignKeyConstraintsColumns[] = $columnName; + } + } + } } diff --git a/tests/Console/ModelsCommand/Relations/Models/BelongsToVariation.php b/tests/Console/ModelsCommand/Relations/Models/BelongsToVariation.php new file mode 100644 index 0000000..f5d85cc --- /dev/null +++ b/tests/Console/ModelsCommand/Relations/Models/BelongsToVariation.php @@ -0,0 +1,31 @@ +belongsTo(self::class, 'not_null_column_with_foreign_key_constraint'); + } + + public function notNullColumnWithNoForeignKeyConstraint(): BelongsTo + { + return $this->belongsTo(self::class, 'not_null_column_with_no_foreign_key_constraint'); + } + + public function nullableColumnWithForeignKeyConstraint(): BelongsTo + { + return $this->belongsTo(self::class, 'nullable_column_with_foreign_key_constraint'); + } + + public function nullableColumnWithNoForeignKeyConstraint(): BelongsTo + { + return $this->belongsTo(self::class, 'nullable_column_with_no_foreign_key_constraint'); + } +} diff --git a/tests/Console/ModelsCommand/Relations/__snapshots__/Test__test__1.php b/tests/Console/ModelsCommand/Relations/__snapshots__/Test__test__1.php index b12568f..445901d 100644 --- a/tests/Console/ModelsCommand/Relations/__snapshots__/Test__test__1.php +++ b/tests/Console/ModelsCommand/Relations/__snapshots__/Test__test__1.php @@ -4,6 +4,59 @@ declare(strict_types=1); namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; + +/** + * Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\Relations\Models\BelongsToVariation + * + * @property integer $id + * @property integer $not_null_column_with_foreign_key_constraint + * @property integer $not_null_column_with_no_foreign_key_constraint + * @property integer|null $nullable_column_with_foreign_key_constraint + * @property integer|null $nullable_column_with_no_foreign_key_constraint + * @property-read BelongsToVariation $notNullColumnWithForeignKeyConstraint + * @property-read BelongsToVariation|null $notNullColumnWithNoForeignKeyConstraint + * @property-read BelongsToVariation|null $nullableColumnWithForeignKeyConstraint + * @property-read BelongsToVariation|null $nullableColumnWithNoForeignKeyConstraint + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation query() + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation whereNotNullColumnWithForeignKeyConstraint($value) + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation whereNotNullColumnWithNoForeignKeyConstraint($value) + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation whereNullableColumnWithForeignKeyConstraint($value) + * @method static \Illuminate\Database\Eloquent\Builder|BelongsToVariation whereNullableColumnWithNoForeignKeyConstraint($value) + * @mixin \Eloquent + */ +class BelongsToVariation extends Model +{ + public function notNullColumnWithForeignKeyConstraint(): BelongsTo + { + return $this->belongsTo(self::class, 'not_null_column_with_foreign_key_constraint'); + } + + public function notNullColumnWithNoForeignKeyConstraint(): BelongsTo + { + return $this->belongsTo(self::class, 'not_null_column_with_no_foreign_key_constraint'); + } + + public function nullableColumnWithForeignKeyConstraint(): BelongsTo + { + return $this->belongsTo(self::class, 'nullable_column_with_foreign_key_constraint'); + } + + public function nullableColumnWithNoForeignKeyConstraint(): BelongsTo + { + return $this->belongsTo(self::class, 'nullable_column_with_no_foreign_key_constraint'); + } +} +bigIncrements('id'); + $table->integer('not_null_column_with_foreign_key_constraint'); + $table->integer('not_null_column_with_no_foreign_key_constraint'); + $table->integer('nullable_column_with_foreign_key_constraint')->nullable(); + $table->integer('nullable_column_with_no_foreign_key_constraint')->nullable(); + $table->foreign('not_null_column_with_foreign_key_constraint')->references('id')->on('belongs_to_variations'); + $table->foreign('nullable_column_with_foreign_key_constraint')->references('id')->on('belongs_to_variations'); + }); + } +}