Model Migration Workflow

  1. Create new model via php artisan make:model -a (Model name, singular form, in PascalCase). This creates the model, migration file, seeder file, model factory, and model controller.

  2. Write the migration file to match proposed schema, being sure to set unique constraints, indices, and foreign keys as appropriate.

  3. Write any mandatory seeder data that should be populated in the Database on install.

  4. Write the model factory, making use of Faker to populate dummy data.

  5. This would be a good time to run a php artisan migrate --seed as well as testing your Model factory with a simple unit test:

    <?php namespace Tests\Unit; use Tests\TestCase; use Wikijump\Models\User; class UserTest extends TestCase { /** * A basic test of the factory. * * @return void */ public function test_models_can_be_instantiated() { $user = User::factory()->make(); $this->assertTrue($user instanceof User); } }
  6. Remove the equivalent table from the seed.sql scripts. Usually there are several places where it is referenced, for example creating the table, then creating the sequence for the primary key, then possibly more ALTER TABLE statements further down.

  7. In the legacy DB classes, modify the base file and base peer file to reference the new schema. The former defines the fields in the table, the latter also references their data types.

  8. In the legacy model, first remove any unused methods. Then for each remaining method, determine if it’s something that’s best replaced with a simple getter or setter from the new model. In Laravel, magic methods exist for single fields in a table. E.g., if there’s an email column for the User, you can make use of a $user->getEmail() method without having to actually define it in the model. Finally, anything that looks more customized should either make use of new models and methods, or if that will be overly burdensome, the method should be imported into the new model until more models are written and the process becomes simpler.

  9. Build unit tests around all your new methods! The behavior needs to be identical between the two. If it makes sense to, bundle a copy of the original method in the test file so you can then assert its output and yours are equal. Tests should go in web/tests/php.

  10. In the remaining codebase, update references to the legacy model with the new model and methods wherever feasible. Please insert a TODO: above any method calls that are not able to be modified and explain why, so we can make them work down the line.

  11. If possible to do so after 7 and 8, remove the legacy model, peer, base model, and base model peer from the codebase.

  12. Once the model is fully removed, include an entry for it in DEADCODE.md.