joshlemer's avatar

Is it bad practice to refer to Models in Migrations?

Just learning Laravel here, but I see these kinds of migrations in the courses:

 public function up(): void
    {
        Schema::create('jobs', function (Blueprint $table) {
            $table->id();
            $table->foreignIdFor(App\Models\Employer::class);
        });
    }

But I can foresee that one day, maybe 2 years from now, and many many migrations later, I might have a major refactoring where I don't end up with having an Employer class at all, but the migrations will still need to run. Or, there may be even more complicated situations where the Employer still exists but the join column is changed or renamed or the relationship goes through a pivot table rather than a belongsToOne relationship.

At that time of refactoring, it seems like it would be a huge pain to go back through the 30 old migrations and meticulously rewrite them. My instinct tells me I should just stick to manual spelling out of the migration columns like

$table->foreignKey('employer_id')->references('id')->on('employers');

Is this your sense as well, or not a big problem?

0 likes
8 replies
jlrdw's avatar

I would advise to not mess with migrations on a production database. I have seen users loose months of data.

If playing with development then migrate all you want.

No matter though, backup first or chance loosing data.

1 like
joshlemer's avatar

@jlrdw

But won't I have to mess with migrations anyways in order to get the code to work for local development and dev environments?

In that case, there is a difference isn't there, between referring to Models (which reflect only the CURRENT domain model) and Migrations code which go back to the beginning of development? If I avoid ever referring to Model classes directly in the migration code, it will tend to be lower maintenance burden wouldn't you say?

Snapey's avatar

Makes no difference. If you change that model you will need to rework any place that model is referenced (including migrations)

Using the table as reference does not help either since if the model goes, you are unlikely to still want the table with that name.

So I would not worry about it. Like the bumper sticker says, 'change happens' . You deal with it as part of your decision to remove a model.

martinbean's avatar

@joshlemer Yes, because the model may change or be completely removed in the lifetime of your application.

Consider this: you create a migration, and reference a Foo model in that migration. Later, your requirements, and the Foo model is removed. From that point on, any one checking out your project—including you—and trying to run migrations afresh is not going to be able to, because they’ll now get an error saying “Foo model is not found” when trying to run that migration.

So, use string to refer to known values such as column and table names.

1 like
martinbean's avatar

@Snapey But it’s something you have to remember to do. It’s essentially creating solutions to problems of your own making.

1 like
Snapey's avatar

@martinbean so what do you do about the employer_id column that still refers to a non existant table

martinbean's avatar

@Snapey I don’t really follow?

If I have a migration that refers to a column, then that column will exist in the database schema at the moment in time of that migration, regardless what any subsequent migrations may do to that table or column.

1 like

Please or to participate in this conversation.