#Call seeder within migration?

11 messages · Page 1 of 1 (latest)

dry lichen
#

I just would like to know how you guys handle default foreign keys in your migrations when creating new tables?

Currently I am writing seeders and call them within the migration, so the next migration can set the default foreign key, as data is provided.

Is this a valid approach, or am I missing a crucial concept maybe?

inner anchor
#

Why are you calling seeders from migrations?

dry lichen
#

With all due respect, did you just read the title?

In case you just need better example / are a visual guy...

New Table:

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('delivery_statuses', function (Blueprint $table) {
            $table->id();
            $table->json('name');
            $table->string('slug')->unique();
            $table->json('description');
            $table->softDeletes();
            $table->timestamps();
        });

        /**
         * ? Why we do this here?
         ** The next migration depends on delivery status and should set
         ** the default value for the foreign key. Without running the Seeder
         ** previously the foreign key would be empty and the migration would fail.
         ** This is a workaround for this problem.
         */
        if (\App\Models\DeliveryStatus::count() < 1) {
            Artisan::call('db:seed', [
                '--class' => \Database\Seeders\DeliveryStatusSeeder::class,
            ]);
        }
    }
};

And here the second migration..

        Schema::table('a_table', function (Blueprint $table) {
            $table->foreignIdFor(\App\Models\DeliveryStatus::class)
                ->default(\App\Models\DeliveryStatus::where('slug', '=', 'none')->first()->id) // Now show me how you do this...
                ->constrained();
        });
inner anchor
#

I skipped the word default, that's why this post didnt make sense to me.

sturdy crest
#

The only alternative is to move the code from the seeder to the migration itself, if that makes more sense. Keep in mind that if you want to dump the schema and prune your migrations in the future, you won't be able to import the dumped schema because the data will be missing.

inner anchor
#

Okay, back: so what I do is: writing the code to create the entities in the migration.

  • create delivery_status table
  • using DeliveryStatus::create() and fetching the desired default id
  • creating the related table that needs the relation, default or whatever
#

I am doing that because that prevents the app from being mutated, as the seeder could be changed anytime, while with migrations you should not do that

#

E.g. once you need to setup a second server, it would have the same structure again

#

Everything is isolated and preserved in that migration handling this very chang

#

brb

sturdy crest
#

I agree with @potent junco . Like I said, this will prevent you from ever using the schema:dump feature.
As an alternative, maybe you could define the default statuses in your relationships, e.g.

public function deliveryStatus(): HasOne
{
    return $this->hasOne(DeliveryStatus::class)
        ->withDefault(function(DeliveryStatus $model) {
            $model->fill([
              // Add default attributes here  
            ])->save();
        });
}