[5.6] Allow "app" migrations to override package migrations #24521
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I was recently helping someone out with an issue where the easiest solution was to override a package migration. I know generally you would want to add a new migration that undoes what the package migration is doing "wrong" and then do what you need, but that option wouldn't work in this case. We ran into some issues, though. After copying the package migration to the app's migration folder, we noticed that the package migration was still taking precedence. This seemed counter-intuitive to me, so we dug into why.
What we found is that the Migrator takes a list of migration paths (provided by this method), enumerates the files within those paths, filters out non-migration files, sorts by filename (date), then runs them in order. The problem is that the map/filter functionality is finding the app version, then overwriting it with the package version of the same name. When it goes to run the migrations, it doesn't even acknowledge the presence of the app copy.
Again, I know the likelihood of you needing to do this is low. In either case, however, it got me thinking. What if a package had an identically-named migration for some reason (perhaps maliciously, perhaps coincidentally)? Your app's migration would never run.
Enter the solution. Let's just reorder the migration paths! Most of Laravel's functionality allows for app versions of files to override package versions of files. I see no reason for this to be treated any differently. In fact, being different will likely just lead to confusion, however small the chance of that is.
This was tested locally with a
dd($files)
here, among other places. With a single migration file duplicated in the app, the only change to that list was which file was loaded. Unfortunately, I don't have screenshots or any other proof, but reproduction should be straightforward enough.If you have any questions or comments, I'm certainly open to hearing about them. I found no mention of this in the docs, so I'm not sure whether to consider this a bugfix for an undocumented feature, or a feature enhancement.