From 403439abb933aa06d13b95161f7162d0afeba43b Mon Sep 17 00:00:00 2001 From: Krishan Koenig Date: Sun, 19 Apr 2020 16:55:37 +0200 Subject: [PATCH] append ->nullable() to nullable relationships - closes #4 --- src/Tasks/AddRelationshipFields.php | 32 +++++- tests/NovaGeneratorTest.php | 1 + .../definitions/nullable-relationships.bp | 4 + .../fixtures/nova/nullable-relationships.php | 97 +++++++++++++++++++ 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/definitions/nullable-relationships.bp create mode 100644 tests/fixtures/nova/nullable-relationships.php diff --git a/src/Tasks/AddRelationshipFields.php b/src/Tasks/AddRelationshipFields.php index 95a3d40..05f2b0e 100644 --- a/src/Tasks/AddRelationshipFields.php +++ b/src/Tasks/AddRelationshipFields.php @@ -4,10 +4,13 @@ use Closure; use Blueprint\Models\Model; +use Illuminate\Support\Arr; use Illuminate\Support\Str; class AddRelationshipFields { + use InteractWithRelationships; + const INDENT = ' '; /** @var Model */ @@ -46,11 +49,17 @@ public function handle(array $data, Closure $next) $fields .= self::INDENT . $fieldType . "::make('" . $label . "'"; - if ($label !== $class && $label !== Str::plural($class)) { + if ($this->classNameNotGuessable($label, $class)) { $fields .= ", '" . $methodName . "', " . $class . '::class'; } - $fields .= '),' . PHP_EOL; + $fields .= ')'; + + if ($this->isNullable($reference)) { + $fields .= '->nullable()'; + } + + $fields .= ',' . PHP_EOL; } $fields .= PHP_EOL; @@ -74,6 +83,25 @@ private function buildMethodName(string $name, string $type) : $name; } + private function classNameNotGuessable($label, $class): bool + { + return $label !== $class + && $label !== Str::plural($class); + } + + private function isNullable($relation): bool + { + $relationColumnName = $this->relationshipIdentifiers($this->model->columns()) + ->filter(function ($relationReference, $columnName) use ($relation) { + return in_array($relationReference, Arr::get($this->model->relationships(), 'belongsTo', [])) + && $columnName === $relation; + }) + ->first(); + + return !is_null($relationColumnName) + && in_array('nullable', $this->model->columns()[$relationColumnName]->modifiers()); + } + private function fieldType(string $dataType): string { static $fieldTypes = [ diff --git a/tests/NovaGeneratorTest.php b/tests/NovaGeneratorTest.php index aec1d27..e34508c 100644 --- a/tests/NovaGeneratorTest.php +++ b/tests/NovaGeneratorTest.php @@ -120,6 +120,7 @@ public function novaTreeDataProvider() ['definitions/with-timezones.bp', 'app/Nova/Comment.php', 'nova/with-timezones.php'], ['definitions/relationships.bp', 'app/Nova/Comment.php', 'nova/relationships.php'], ['definitions/unconventional.bp', 'app/Nova/Team.php', 'nova/unconventional.php'], + ['definitions/nullable-relationships.bp', 'app/Nova/Subscription.php', 'nova/nullable-relationships.php'], /* * @todo work on this */ diff --git a/tests/fixtures/definitions/nullable-relationships.bp b/tests/fixtures/definitions/nullable-relationships.bp new file mode 100644 index 0000000..e910492 --- /dev/null +++ b/tests/fixtures/definitions/nullable-relationships.bp @@ -0,0 +1,4 @@ +models: + Subscription: + user_id: id nullable + item_id: id:product diff --git a/tests/fixtures/nova/nullable-relationships.php b/tests/fixtures/nova/nullable-relationships.php new file mode 100644 index 0000000..667c585 --- /dev/null +++ b/tests/fixtures/nova/nullable-relationships.php @@ -0,0 +1,97 @@ +sortable(), + + BelongsTo::make('User')->nullable(), + BelongsTo::make('Item', 'item', Product::class), + + DateTime::make('Created at'), + DateTime::make('Updated at'), + ]; + } + + /** + * Get the cards available for the request. + * + * @param \Illuminate\Http\Request $request + * @return array + */ + public function cards(Request $request) + { + return []; + } + + /** + * Get the filters available for the resource. + * + * @param \Illuminate\Http\Request $request + * @return array + */ + public function filters(Request $request) + { + return []; + } + + /** + * Get the lenses available for the resource. + * + * @param \Illuminate\Http\Request $request + * @return array + */ + public function lenses(Request $request) + { + return []; + } + + /** + * Get the actions available for the resource. + * + * @param \Illuminate\Http\Request $request + * @return array + */ + public function actions(Request $request) + { + return []; + } +}