diff --git a/src/Blueprint.php b/src/Blueprint.php index d14f245c..3d2f916a 100644 --- a/src/Blueprint.php +++ b/src/Blueprint.php @@ -65,8 +65,8 @@ public function parse($content, $strip_dashes = true) ); $content = preg_replace_callback( - '/^(\s+)uuid(: true)?$/mi', - fn ($matches) => $matches[1] . 'id: uuid primary', + '/^(\s+)(ulid|uuid)(: true)?$/mi', + fn ($matches) => $matches[1] . 'id: ' . $matches[2] . ' primary', $content ); diff --git a/src/Generators/FactoryGenerator.php b/src/Generators/FactoryGenerator.php index 87f76d35..04d5ffa1 100644 --- a/src/Generators/FactoryGenerator.php +++ b/src/Generators/FactoryGenerator.php @@ -110,7 +110,7 @@ protected function buildDefinition(Model $model): string $definition .= sprintf('%s::factory()->create()->%s', $class, $key); $definition .= ',' . PHP_EOL; } - } elseif ($column->dataType() === 'id' || ($column->dataType() === 'uuid' && Str::endsWith($column->name(), '_id'))) { + } elseif ($column->dataType() === 'id' || (in_array($column->dataType(), ['uuid', 'ulid']) && Str::endsWith($column->name(), '_id'))) { $name = Str::beforeLast($column->name(), '_id'); $class = Str::studly($column->attributes()[0] ?? $name); $reference = $this->fullyQualifyModelReference($class) ?? $model; @@ -156,6 +156,10 @@ protected function buildDefinition(Model $model): string $definition .= str_repeat(self::INDENT, 3) . "'{$column->name()}' => "; $definition .= 'Str::random(10)'; $definition .= ',' . PHP_EOL; + } elseif ($column->dataType() === 'ulid') { + $definition .= str_repeat(self::INDENT, 3) . "'{$column->name()}' => "; + $definition .= '(string) Str::ulid()'; + $definition .= ',' . PHP_EOL; } else { $definition .= str_repeat(self::INDENT, 3) . "'{$column->name()}' => "; diff --git a/src/Generators/MigrationGenerator.php b/src/Generators/MigrationGenerator.php index 0910e2fa..bf4cb6c1 100644 --- a/src/Generators/MigrationGenerator.php +++ b/src/Generators/MigrationGenerator.php @@ -71,7 +71,7 @@ public function output(Tree $tree, $overwrite = false): array if (!empty($model->pivotTables())) { foreach ($model->pivotTables() as $pivotSegments) { $pivotTableName = $this->getPivotTableName($pivotSegments); - $tables['pivotTableNames'][$pivotTableName] = $this->populatePivotStub($stub, $pivotSegments); + $tables['pivotTableNames'][$pivotTableName] = $this->populatePivotStub($stub, $pivotSegments, $tree->models()); } } @@ -128,10 +128,10 @@ protected function populateStub(string $stub, Model $model): string return $stub; } - protected function populatePivotStub(string $stub, array $segments): string + protected function populatePivotStub(string $stub, array $segments, array $models = []): string { $stub = str_replace('{{ table }}', $this->getPivotTableName($segments), $stub); - $stub = str_replace('{{ definition }}', $this->buildPivotTableDefinition($segments), $stub); + $stub = str_replace('{{ definition }}', $this->buildPivotTableDefinition($segments, $models), $stub); if ($this->hasForeignKeyConstraints) { $stub = $this->disableForeignKeyConstraints($stub); @@ -194,7 +194,7 @@ protected function buildDefinition(Model $model): string ); } - if (!empty($columnAttributes) && !$this->isIdOrUuid($column->dataType())) { + if (!empty($columnAttributes) && !$this->isIdColumnType($column->dataType())) { $column_definition .= ', '; if (in_array($column->dataType(), ['set', 'enum'])) { @@ -221,7 +221,7 @@ protected function buildDefinition(Model $model): string $column->modifiers() ); - if ($this->isIdOrUuid($column->dataType())) { + if ($this->isIdColumnType($column->dataType())) { $column_definition = $foreign; $foreign = ''; } @@ -232,7 +232,7 @@ protected function buildDefinition(Model $model): string || (is_array($modifier) && key($modifier) === 'onDelete') || (is_array($modifier) && key($modifier) === 'onUpdate') || $modifier === 'foreign' - || ($modifier === 'nullable' && $this->isIdOrUuid($column->dataType())) + || ($modifier === 'nullable' && $this->isIdColumnType($column->dataType())) ); } @@ -290,10 +290,9 @@ protected function buildDefinition(Model $model): string return trim($definition); } - protected function buildPivotTableDefinition(array $segments): string + protected function buildPivotTableDefinition(array $segments, array $models = []): string { $definition = ''; - foreach ($segments as $segment) { $column = Str::before(Str::snake($segment), ':'); $references = 'id'; @@ -304,13 +303,49 @@ protected function buildPivotTableDefinition(array $segments): string $this->hasForeignKeyConstraints = true; $definition .= $this->buildForeignKey($foreign, $on, 'id') . ';' . PHP_EOL; } else { - $definition .= self::INDENT . '$table->foreignId(\'' . $foreign . '\');' . PHP_EOL; + $definition .= $this->generateForeignKeyDefinition($segment, $foreign, $models); } } return trim($definition); } + /** + * Generates the foreign key definition for a pivot table. + * + * This function generates the foreign key definition for a pivot table in a migration file. + * It checks if the model exists and its name matches the pivot table segment. If it does, + * it determines the data type of the primary key and appends the appropriate method call + * to the `$definition` string. If the model does not exist or its name does not match the + * pivot table segment, it defaults to appending `$table->foreignId(\'' . $foreignKeyColumnName . '\');` + * to the `$definition` string. The function then returns the `$definition` string. + * + * @param string $pivotTableSegment The segment of the pivot table. e.g 'dive_job' it would be 'Dive' or 'Job'. + * @param string $foreignKeyColumnName The name of the foreign key column. e.g 'dive_id' or 'job_id'. + * @param array $models An array of models. e.g ['Dive' => $diveModel, 'Job' => $jobModel]. + * @return string The foreign key definition. e.g '$table->foreignUlid('dive_id');' + */ + protected function generateForeignKeyDefinition(string $pivotTableSegment, string $foreignKeyColumnName, array $models = []): string + { + $definition = self::INDENT; + if (count($models) > 0 && array_key_exists($pivotTableSegment, $models)) { + $model = $models[$pivotTableSegment]; + if ($model->name() === $pivotTableSegment) { + $dataType = $model->columns()[$model->primaryKey()]->dataType(); + $definition .= match ($dataType) { + 'ulid' => '$table->foreignUlid(\'' . $foreignKeyColumnName . '\');', + 'uuid' => '$table->foreignUuid(\'' . $foreignKeyColumnName . '\');', + default => '$table->foreignId(\'' . $foreignKeyColumnName . '\');', + }; + } + } else { + $definition .= '$table->foreignId(\'' . $foreignKeyColumnName . '\');'; + } + $definition .= PHP_EOL; + + return $definition; + } + protected function buildPolyTableDefinition(string $parentTable): string { $definition = ''; @@ -347,7 +382,7 @@ protected function buildForeignKey(string $column_name, ?string $on, string $typ $column = Str::afterLast($column_name, '_'); } - if ($this->isIdOrUuid($type) && !empty($attributes)) { + if ($this->isIdColumnType($type) && !empty($attributes)) { $table = Str::lower(Str::plural($attributes[0])); } @@ -364,12 +399,12 @@ protected function buildForeignKey(string $column_name, ?string $on, string $typ $on_update_suffix = self::ON_UPDATE_CLAUSES[$on_update_clause]; } - if ($this->isIdOrUuid($type)) { - if ($type === 'uuid') { - $method = 'foreignUuid'; - } else { - $method = 'foreignId'; - } + if ($this->isIdColumnType($type)) { + $method = match ($type) { + 'ulid' => 'foreignUlid', + 'uuid' => 'foreignUuid', + default => 'foreignId', + }; $prefix = in_array('nullable', $modifiers) ? '$table->' . "{$method}('{$column_name}')->nullable()" @@ -381,7 +416,6 @@ protected function buildForeignKey(string $column_name, ?string $on, string $typ if ($on_update_clause === 'cascade') { $on_update_suffix = '->cascadeOnUpdate()'; } - if ($column_name === Str::singular($table) . '_' . $column) { return self::INDENT . "{$prefix}->constrained(){$on_delete_suffix}{$on_update_suffix}"; } @@ -469,7 +503,7 @@ private function shouldAddForeignKeyConstraint(\Blueprint\Models\Column $column) } return config('blueprint.use_constraints') - && ($this->isIdOrUuid($column->dataType()) && Str::endsWith($column->name(), '_id')); + && ($this->isIdColumnType($column->dataType()) && Str::endsWith($column->name(), '_id')); } protected function isNumericDefault(string $type, string $value): bool @@ -486,8 +520,8 @@ protected function isNumericDefault(string $type, string $value): bool ->contains(fn ($value) => strtolower($value) === strtolower($type)); } - protected function isIdOrUuid(string $dataType): bool + protected function isIdColumnType(string $dataType): bool { - return in_array($dataType, ['id', 'uuid']); + return in_array($dataType, ['id', 'ulid', 'uuid']); } } diff --git a/src/Generators/ModelGenerator.php b/src/Generators/ModelGenerator.php index 1f7cabef..7b9bddec 100644 --- a/src/Generators/ModelGenerator.php +++ b/src/Generators/ModelGenerator.php @@ -90,6 +90,16 @@ protected function buildClassPhpDoc(Model $model): string $phpDoc .= PHP_EOL; $phpDoc .= ' * @property string|null $' . $column->name() . '_type'; $phpDoc .= PHP_EOL; + } elseif ($column->dataType() === 'ulidMorphs') { + $phpDoc .= ' * @property string $' . $column->name() . '_id'; + $phpDoc .= PHP_EOL; + $phpDoc .= ' * @property string $' . $column->name() . '_type'; + $phpDoc .= PHP_EOL; + } elseif ($column->dataType() === 'nullableUlidMorphs') { + $phpDoc .= ' * @property string|null $' . $column->name() . '_id'; + $phpDoc .= PHP_EOL; + $phpDoc .= ' * @property string|null $' . $column->name() . '_type'; + $phpDoc .= PHP_EOL; } elseif ($column->dataType() === 'uuidMorphs') { $phpDoc .= ' * @property string $' . $column->name() . '_id'; $phpDoc .= PHP_EOL; @@ -278,6 +288,11 @@ protected function addTraits(Model $model, $stub): string $traits[] = 'SoftDeletes'; } + if ($model->usesUlids()) { + $this->addImport($model, 'Illuminate\\Database\\Eloquent\\Concerns\\HasUlids'); + $traits[] = 'HasUlids'; + } + if ($model->usesUuids()) { $this->addImport($model, 'Illuminate\\Database\\Eloquent\\Concerns\\HasUuids'); $traits[] = 'HasUuids'; diff --git a/src/Lexers/ModelLexer.php b/src/Lexers/ModelLexer.php index dcf195fb..f4d2f268 100644 --- a/src/Lexers/ModelLexer.php +++ b/src/Lexers/ModelLexer.php @@ -81,6 +81,7 @@ class ModelLexer implements Lexer 'unsignedmediuminteger' => 'unsignedMediumInteger', 'unsignedsmallinteger' => 'unsignedSmallInteger', 'unsignedtinyinteger' => 'unsignedTinyInteger', + 'ulid' => 'ulid', 'uuid' => 'uuid', 'year' => 'year', ]; diff --git a/src/Models/Model.php b/src/Models/Model.php index cee66fd7..e9cc3723 100644 --- a/src/Models/Model.php +++ b/src/Models/Model.php @@ -96,6 +96,11 @@ public function usesPrimaryKey(): bool return $this->primaryKey !== false; } + public function usesUlids(): bool + { + return $this->usesPrimaryKey() && $this->columns[$this->primaryKey]->dataType() === 'ulid'; + } + public function usesUuids(): bool { return $this->usesPrimaryKey() && $this->columns[$this->primaryKey]->dataType() === 'uuid'; diff --git a/tests/Feature/BlueprintTest.php b/tests/Feature/BlueprintTest.php index 2cb1d459..659bcb9d 100644 --- a/tests/Feature/BlueprintTest.php +++ b/tests/Feature/BlueprintTest.php @@ -117,6 +117,22 @@ public function it_parses_shorthands(): void ], $this->subject->parse($blueprint)); } + #[Test] + public function it_parses_ulid_shorthand(): void + { + $blueprint = $this->fixture('drafts/ulid-shorthand.yaml'); + + $this->assertEquals([ + 'models' => [ + 'Person' => [ + 'id' => 'ulid primary', + 'timestamps' => 'timestamps', + 'company_id' => 'ulid', + ], + ], + ], $this->subject->parse($blueprint)); + } + #[Test] public function it_parses_uuid_shorthand(): void { diff --git a/tests/Feature/Generators/MigrationGeneratorTest.php b/tests/Feature/Generators/MigrationGeneratorTest.php index b29d8938..c4330475 100644 --- a/tests/Feature/Generators/MigrationGeneratorTest.php +++ b/tests/Feature/Generators/MigrationGeneratorTest.php @@ -150,6 +150,35 @@ public function output_creates_constraints_for_unconventional_foreign_reference_ $this->assertEquals(['created' => [$model_migration]], $this->subject->output($tree)); } + #[Test] + public function using_ulids_output_also_creates_pivot_table_migration(): void + { + $this->filesystem->expects('stub') + ->with('migration.stub') + ->andReturn($this->stub('migration.stub')); + + $now = Carbon::now(); + Carbon::setTestNow($now); + + $journey_model_migration = str_replace('timestamp', $now->copy()->subSeconds(2)->format('Y_m_d_His'), 'database/migrations/timestamp_create_journeys_table.php'); + $diary_model_migration = str_replace('timestamp', $now->copy()->subSecond()->format('Y_m_d_His'), 'database/migrations/timestamp_create_diaries_table.php'); + $pivot_migration = str_replace('timestamp', $now->format('Y_m_d_His'), 'database/migrations/timestamp_create_diary_journey_table.php'); + + $this->filesystem->expects('exists')->times(3)->andReturn(false); + + $this->filesystem->expects('put') + ->with($journey_model_migration, $this->fixture('migrations/belongs-to-many-using-ulids-journey-model.php')); + $this->filesystem->expects('put') + ->with($diary_model_migration, $this->fixture('migrations/belongs-to-many-using-ulids-diary-model.php')); + $this->filesystem->expects('put') + ->with($pivot_migration, $this->fixture('migrations/belongs-to-many-pivot-using-ulids.php')); + + $tokens = $this->blueprint->parse($this->fixture('drafts/belongs-to-many-using-ulids.yaml')); + $tree = $this->blueprint->analyze($tokens); + + $this->assertEquals(['created' => [$journey_model_migration, $diary_model_migration, $pivot_migration]], $this->subject->output($tree)); + } + #[Test] public function output_also_creates_pivot_table_migration(): void { @@ -527,6 +556,9 @@ public static function modelTreeDataProvider() ['drafts/optimize.yaml', 'database/migrations/timestamp_create_optimizes_table.php', 'migrations/optimize.php'], ['drafts/model-key-constraints.yaml', 'database/migrations/timestamp_create_orders_table.php', 'migrations/model-key-constraints.php'], ['drafts/disable-auto-columns.yaml', 'database/migrations/timestamp_create_states_table.php', 'migrations/disable-auto-columns.php'], + ['drafts/ulid-shorthand.yaml', 'database/migrations/timestamp_create_people_table.php', 'migrations/ulid-shorthand.php'], + ['drafts/ulid-shorthand-invalid-relationship.yaml', 'database/migrations/timestamp_create_age_cohorts_table.php', 'migrations/ulid-shorthand-invalid-relationship.php'], + ['drafts/ulid-without-relationship.yaml', 'database/migrations/timestamp_create_vats_table.php', 'migrations/ulid-without-relationship.php'], ['drafts/uuid-shorthand.yaml', 'database/migrations/timestamp_create_people_table.php', 'migrations/uuid-shorthand.php'], ['drafts/uuid-shorthand-invalid-relationship.yaml', 'database/migrations/timestamp_create_age_cohorts_table.php', 'migrations/uuid-shorthand-invalid-relationship.php'], ['drafts/uuid-without-relationship.yaml', 'database/migrations/timestamp_create_vats_table.php', 'migrations/uuid-without-relationship.php'], diff --git a/tests/Feature/Generators/ModelGeneratorTest.php b/tests/Feature/Generators/ModelGeneratorTest.php index eb8b2b6f..52f88a17 100644 --- a/tests/Feature/Generators/ModelGeneratorTest.php +++ b/tests/Feature/Generators/ModelGeneratorTest.php @@ -642,6 +642,7 @@ public static function modelTreeDataProvider(): array ['drafts/uuid-shorthand-invalid-relationship.yaml', 'app/Models/AgeCohort.php', 'models/uuid-shorthand-invalid-relationship.php'], ['drafts/model-with-meta.yaml', 'app/Models/Post.php', 'models/model-with-meta.php'], ['drafts/infer-belongsto.yaml', 'app/Models/Conference.php', 'models/infer-belongsto.php'], + ['drafts/model-with-ulid-id.yaml', 'app/Models/User.php', 'models/model-with-ulid-trait.php'], ['drafts/model-with-uuid-id.yaml', 'app/Models/User.php', 'models/model-with-uuid-trait.php'], ]; } diff --git a/tests/fixtures/drafts/all-column-types.yaml b/tests/fixtures/drafts/all-column-types.yaml index 123d44fe..7311b6db 100644 --- a/tests/fixtures/drafts/all-column-types.yaml +++ b/tests/fixtures/drafts/all-column-types.yaml @@ -25,11 +25,13 @@ models: mediumInteger: mediumInteger mediumText: mediumText morphs: morphs + ulidMorphs: ulidMorphs uuidMorphs: uuidMorphs multiLineString: multiLineString multiPoint: multiPoint multiPolygon: multiPolygon nullableMorphs: nullableMorphs + nullableUlidMorphs: nullableUuidMorphs nullableUuidMorphs: nullableUuidMorphs nullableTimestamps: nullableTimestamps point: point @@ -50,5 +52,6 @@ models: unsignedMediumInteger: unsignedMediumInteger unsignedSmallInteger: unsignedSmallInteger unsignedTinyInteger: unsignedTinyInteger + ulid: ulid uuid: uuid year: year diff --git a/tests/fixtures/drafts/belongs-to-many-using-ulids.yaml b/tests/fixtures/drafts/belongs-to-many-using-ulids.yaml new file mode 100644 index 00000000..7ec717f3 --- /dev/null +++ b/tests/fixtures/drafts/belongs-to-many-using-ulids.yaml @@ -0,0 +1,11 @@ +models: + Journey: + ulid + name: string + user_id: ulid foreign + relationships: + belongsToMany: Diary + Diary: + ulid + relationships: + belongsToMany: Journey diff --git a/tests/fixtures/drafts/model-key-constraints.yaml b/tests/fixtures/drafts/model-key-constraints.yaml index ce109f72..4cb9f9ba 100644 --- a/tests/fixtures/drafts/model-key-constraints.yaml +++ b/tests/fixtures/drafts/model-key-constraints.yaml @@ -6,3 +6,5 @@ models: sub_id: uuid foreign:subscription expires_at: timestamp nullable index meta: json default:'[]' + customer_id: ulid foreign + tran_id: ulid foreign:transaction diff --git a/tests/fixtures/drafts/model-with-ulid-id.yaml b/tests/fixtures/drafts/model-with-ulid-id.yaml new file mode 100644 index 00000000..d0b8183b --- /dev/null +++ b/tests/fixtures/drafts/model-with-ulid-id.yaml @@ -0,0 +1,5 @@ +models: + User: + ulid + name: string + base_pay: decimal:10,2 diff --git a/tests/fixtures/drafts/ulid-shorthand-invalid-relationship.yaml b/tests/fixtures/drafts/ulid-shorthand-invalid-relationship.yaml new file mode 100644 index 00000000..9c0e431a --- /dev/null +++ b/tests/fixtures/drafts/ulid-shorthand-invalid-relationship.yaml @@ -0,0 +1,9 @@ +models: + AgeCohort: + id + timestamps + name: string:100 + description: string:500 nullable + min_age: integer nullable + max_age: integer nullable + ulid: ulid unique diff --git a/tests/fixtures/drafts/ulid-shorthand.yaml b/tests/fixtures/drafts/ulid-shorthand.yaml new file mode 100644 index 00000000..f892cec2 --- /dev/null +++ b/tests/fixtures/drafts/ulid-shorthand.yaml @@ -0,0 +1,5 @@ +models: + Person: + ulid + company_id: ulid + timestamps diff --git a/tests/fixtures/drafts/ulid-without-relationship.yaml b/tests/fixtures/drafts/ulid-without-relationship.yaml new file mode 100644 index 00000000..688eefd0 --- /dev/null +++ b/tests/fixtures/drafts/ulid-without-relationship.yaml @@ -0,0 +1,3 @@ +models: + Vat: + ulid: ulid diff --git a/tests/fixtures/factories/all-column-types.php b/tests/fixtures/factories/all-column-types.php index 741b3ad8..d45699b2 100644 --- a/tests/fixtures/factories/all-column-types.php +++ b/tests/fixtures/factories/all-column-types.php @@ -46,6 +46,7 @@ public function definition(): array 'mediumText' => $this->faker->text(), 'morphs_id' => $this->faker->randomDigitNotNull(), 'morphs_type' => $this->faker->word(), + 'ulidMorphs' => $this->faker->word(), 'uuidMorphs' => $this->faker->word(), 'multiLineString' => $this->faker->word(), 'multiPoint' => $this->faker->word(), @@ -68,6 +69,7 @@ public function definition(): array 'unsignedMediumInteger' => $this->faker->randomNumber(), 'unsignedSmallInteger' => $this->faker->randomNumber(), 'unsignedTinyInteger' => $this->faker->randomDigitNotNull(), + 'ulid' => (string) Str::ulid(), 'uuid' => $this->faker->uuid(), 'year' => $this->faker->year(), ]; diff --git a/tests/fixtures/factories/model-key-constraints.php b/tests/fixtures/factories/model-key-constraints.php index 3cd3dc09..2e270d11 100644 --- a/tests/fixtures/factories/model-key-constraints.php +++ b/tests/fixtures/factories/model-key-constraints.php @@ -4,8 +4,10 @@ use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; +use App\Models\Customer; use App\Models\Order; use App\Models\Subscription; +use App\Models\Transaction; use App\Models\User; class OrderFactory extends Factory @@ -28,6 +30,8 @@ public function definition(): array 'sub_id' => Subscription::factory(), 'expires_at' => $this->faker->dateTime(), 'meta' => '[]', + 'customer_id' => Customer::factory(), + 'tran_id' => Transaction::factory(), ]; } } diff --git a/tests/fixtures/migrations/belongs-to-many-pivot-using-ulids.php b/tests/fixtures/migrations/belongs-to-many-pivot-using-ulids.php new file mode 100644 index 00000000..60445c38 --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-pivot-using-ulids.php @@ -0,0 +1,31 @@ +foreignUlid('diary_id'); + $table->foreignUlid('journey_id'); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('diary_journey'); + } +}; diff --git a/tests/fixtures/migrations/belongs-to-many-using-ulids-diary-model.php b/tests/fixtures/migrations/belongs-to-many-using-ulids-diary-model.php new file mode 100644 index 00000000..96987a13 --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-using-ulids-diary-model.php @@ -0,0 +1,31 @@ +ulid('id')->primary(); + $table->timestamps(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('diaries'); + } +}; diff --git a/tests/fixtures/migrations/belongs-to-many-using-ulids-journey-model.php b/tests/fixtures/migrations/belongs-to-many-using-ulids-journey-model.php new file mode 100644 index 00000000..831e41fb --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-using-ulids-journey-model.php @@ -0,0 +1,33 @@ +ulid('id')->primary(); + $table->string('name'); + $table->foreignUlid('user_id')->constrained(); + $table->timestamps(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('journeys'); + } +}; diff --git a/tests/fixtures/migrations/model-key-constraints.php b/tests/fixtures/migrations/model-key-constraints.php index 60834d68..0526a610 100644 --- a/tests/fixtures/migrations/model-key-constraints.php +++ b/tests/fixtures/migrations/model-key-constraints.php @@ -20,6 +20,8 @@ public function up(): void $table->foreignUuid('sub_id')->constrained('subscriptions'); $table->timestamp('expires_at')->nullable()->index(); $table->json('meta')->default('[]'); + $table->foreignUlid('customer_id')->constrained(); + $table->foreignUlid('tran_id')->constrained('transactions'); $table->timestamps(); }); diff --git a/tests/fixtures/migrations/ulid-shorthand-invalid-relationship.php b/tests/fixtures/migrations/ulid-shorthand-invalid-relationship.php new file mode 100644 index 00000000..c72a0cd5 --- /dev/null +++ b/tests/fixtures/migrations/ulid-shorthand-invalid-relationship.php @@ -0,0 +1,32 @@ +id(); + $table->string('name', 100); + $table->string('description', 500)->nullable(); + $table->integer('min_age')->nullable(); + $table->integer('max_age')->nullable(); + $table->ulid('ulid')->unique(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('age_cohorts'); + } +}; diff --git a/tests/fixtures/migrations/ulid-shorthand.php b/tests/fixtures/migrations/ulid-shorthand.php new file mode 100644 index 00000000..482cb24b --- /dev/null +++ b/tests/fixtures/migrations/ulid-shorthand.php @@ -0,0 +1,28 @@ +ulid('id')->primary(); + $table->ulid('company_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('people'); + } +}; diff --git a/tests/fixtures/migrations/ulid-without-relationship.php b/tests/fixtures/migrations/ulid-without-relationship.php new file mode 100644 index 00000000..f51c5750 --- /dev/null +++ b/tests/fixtures/migrations/ulid-without-relationship.php @@ -0,0 +1,28 @@ +id(); + $table->ulid('ulid'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('vats'); + } +}; diff --git a/tests/fixtures/models/all-column-types.php b/tests/fixtures/models/all-column-types.php index be6427be..b8b8f227 100644 --- a/tests/fixtures/models/all-column-types.php +++ b/tests/fixtures/models/all-column-types.php @@ -39,11 +39,13 @@ class AllType extends Model 'mediumInteger', 'mediumText', 'morphs', + 'ulidMorphs', 'uuidMorphs', 'multiLineString', 'multiPoint', 'multiPolygon', 'nullableMorphs', + 'nullableUlidMorphs', 'nullableUuidMorphs', 'nullableTimestamps', 'point', @@ -64,6 +66,7 @@ class AllType extends Model 'unsignedMediumInteger', 'unsignedSmallInteger', 'unsignedTinyInteger', + 'ulid', 'uuid', 'year', ]; diff --git a/tests/fixtures/models/model-with-ulid-trait.php b/tests/fixtures/models/model-with-ulid-trait.php new file mode 100644 index 00000000..5738e6ef --- /dev/null +++ b/tests/fixtures/models/model-with-ulid-trait.php @@ -0,0 +1,31 @@ + 'decimal:2', + ]; +}