A title for your blog

Learning Elixir, Phoenix and Ash Part 7: Migrations

Ash Postgres has taken an interesting approach to database migrations which, on one hand I quite like, but on the other keeps tripping me up.

You don’t have to create migrations explicitly (there’s that word again). When you make a change to a resource you can run

mix ash_postgres.generate_migrations name_of_migration

and Ash will diff the current schema against your resources and generate the migration for you like magic. It’s very cool.

The Rails way is intentional. If you want to add an attribute to a model you have to add it with a database migration. There’s no code in the model to indicate that there is an attribute. This is an actual pain. Having to check the database schema to see which attributes a model has. This is so annoying that there have been Rails plugins to write the table schema into a big comment at the top of your model file.

Ash on the other hand defines the attributes in the resource which is definitely an improvement.

The other problem with the Rails Way™ is forgetting to add indexes which is why tools like DatabaseConsistency exist. Every Rails app I have worked on has had missing indexes, eg. validates_presence without a NOT NULL index in the database.

Ash handles tables, columns, indexes, the whole shebang. But the problem with the Ash way is forgetting to run the migation generator. I’ll be coding for a few hours and something will break and remind me that I haven’t migrated the database. Then I have to figure out what has changed since I last did a migration. Or I’ll just run the generator and have all sorts of random changes in the file.

Also because of this I find co-ordination is tricky. If I’m switching between my desktop and laptop I sometimes end up with clashing schemas. I wonder what this is like working with a large team. Admittedly this is because I’m randomly hacking on a toy project rather than doing production work.

What would be cool is something like Guard that watches for file changes and then runs the migration generator on each file change. The generator already knows when there are no schema changes

Generating Migrations:
No changes detected, so no migrations or snapshots have been created.

You could just trust in Ash and ignore the migrations. By that I mean leave the default name and not worry about the contents. Or better still if there was a way for Ash to create separate, properly named migration files for each change. I think this would be possible because Ash creates snapshot files for each resource when it creates the migrations so it I think it knows enough to do that.

I expect as I become more comfortable with Ash my ways of working will settle down and random migrations won’t be a problem anymore. 🤞🏼

#ash #elixir #phoenix