Laravel packages: Load or publish migrations?

Because a “re-declared” class exists and it’s a problem

Photo by Diana Polekhina on Unsplash

As a Laravel package author, mostly for my own projects, adding migrations to add database persistence to something was always something like a problem rather than a solution.

The way Laravel suggests to make available migrations — files that allow to create, update and delete tables from the database — to the developer is to use the loadMigrationsFrom() method of your package Service Provider.

The method basically sets the path that the migrator should explore and discover migrations. This is done when the user calls the migration command php artisan migrate.

The thing is, every time the user migrates, these the tables from the package will be created as declared, meaning, there is no way to edit them. If the user copies them to his project and and migrates, PHP will panic saying these are already declared.

Since in my Laraconfig package I need the migrations to be editable by the developer — as is the case when dealing with tables that connect to userland tables — then we use publish these files instead of loading them.

We will treat the migrations as publishable assets using publishes() and the migrations tag.

As you can see, the code is so dirty I would need to clean my eyes with soap. This is because we need the source file path, the destination file path, and on the destination we have to format the migration file name with the current timestamp. We can’t just put the migrations folder as the timestamp could get into the order of other migrations, specially when dealing with foreign constraints.

Since I like to be lazy when dealing with this shenanigans, I created a simple trait that you an I can attach to a Service Provider. It will deal automatically with the naming and publishing of our migration files of our package.

Using that trait, we can publish are our migrations with only dealing with their respective full paths with using just one method call in the boot() method.

That makes our code cleaner, and hopefully, resolves in one line how to push migrations files to the developer instead of just blindly loading them.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store