Skip to content
Advertisement

Can you delete models referenced in migrations with foreignIdFor()?

I have an old migration where I used the foreignIdFor() method to create a column.

I later decided to delete the model which was referenced and now, when I do a migrate:refresh locally, that migration triggers an error saying that the model doesn’t exist, of course.

So, should one never delete models referenced with foreignIdFor() and use unsignedBigInteger()instead ?

EDIT:

I know foreignIdFor and unsignedBigInteger will create the same column. When I say I deleted the model, I mean the model class, not a model.

My migration file :

<?php

use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
use AppModelsEvent;
use AppModelsOutlookCategory;

class CreateEventOutlookCategoryTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('event_outlook_category', function (Blueprint $table) {
            $table->id();
            $table->foreignIdFor(Event::class);
            $table->foreignIdFor(OutlookCategory::class);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('event_outlook_category');
    }
}

Advertisement

Answer

The foreignIdFor method adds a {column}_id UNSIGNED BIGINT equivalent column for a given model class, so using unsignedBigInteger() doesn’t make any difference.

Resources:

What you could/needed to do is to add cascade delete, and make sure that whenever associated model is deleted, all related models are deleted too.

You could do it like this:

table->foreignId('column_name_id')
      ->constrained()
      ->onDelete('cascade');

Resources:

Answer to the edit:

If you delete Model that was used in foreignIdFor, that method will not be able to understand what you are referencing, and therefore it will fail. So, the answer to your question is YES and NO.

Let me elaborate. If your migrations will be run just once, on the production environment, for example, then you will be able to delete the model you’ve been referencing in the previous migrations and just create a new migration that will cleanup those columns.

In all other cases, when your migrations will be run for a few times (locally when you use migrate:fresh), you need to have Model that was referenced in them in your code base in order for it to work properly.

If you want to avoid these kind of problems that you are experiencing right now, just use unsignedBigInteger and pass to it string that is the name of the column, and you don’t have to worry about deleting the model. However, you will still need to pay attention not to delete the column that is referenced there, because you will get another error for missing column.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement