“Classic” rails approach with plain classes named starting with timestamps. Migrations are sorted by name then applied one by one.
Namespaced version of 1.. Proved to be overkill. Creating more problems than it solves.
Git-like approach with explicit dependencies. Not sure it even worth implementing but since it’s still in my mind, I’d like to share it.
Migration class would look like the following:
class MyMigration extends Migration
{
...
public static function parent(): string
{
return ParentMigration::class;
}
}
parent links current migration to migration it depends on. The method could be generated when doing migrate create based on the current state.
So migrations would be like the following:
p1 was created in a branch that was started from m2 state, n1 was created in a branch started from m3.
When doing migrate up we have to check all migration files and create a flat structure based on it. For example, we’re in the state m1 and want to migrate. Then the sequence could be:
m2
p1
m3
n1
n2
n3
m4
Potentially such approach may result in less conflict situations with extensions but it, for sure, complicates overall mechanism with graph resolving.
This definitely sounds like an overkill. It could be useful in CMS with some plugins system, but for most apps you have linear history and defining dependencies graph for migrations looks like unnecessary complication.
From branch perspective migration dependencies are always linear. You never have case when some migration depends on migration created in the future - migration either already exists in this particular branch or it is irrelevant.
This feature will be only useful for reverting with non-linear history - you can ensure that migration will not be reverted if other migrations depends on it. But for regular apps usually it is easier to not rely on ./yii migrate/down, and just create another migration which will perform revert operations in up() - you will get simple linear migrations history and straight upgrade path.
I vote for the first option mentioned in the opening post.
I don’t see why migrations should be over-complicated. I think the problem that explicit dependencies would solve is something that should be solved in the workflow of application development. Before a branch is merged, the developer that worked on that branch should have the responsibility to check whether new migrations were added in the meantime (while merging back these changes). If necessary, he can simply rename the migration and be done with it.
Option 1 suffices for most of use cases & simplicity.
Does that differ from Yii2 approach … ?
In my experience, down migrations are often not backward compatible with reverse up migrations. Often I would have to write the down migration as a part of next “up” migration (e.g. do few extra database checks).