6 => Model Factories & Database Seeding
The application now has all of the tables it needs in the database that were built previously. If the application needs to move to a different machine or a developer is attempting to add new features on a monolithic development machine they'll need a database that has the same table structure and configuration to do testing on. The tables in the database can easily be created with the migrations that were previously written although the only problem is the database tables created are now empty, but they can be populated by using the application models factory methods. This entry in the blog series will cover how create, use and automate model factories in your application.
Creating Factories
Yet again the php artisan command comes in handy, making it extremely easy to make a factory. For this project one of the commands I used to make a factory was the following.
This creates a file named BoardFactory located at app_root / database / factories / BoardFactory.php
Artisan creates both a definition method and a configure method. The contents of the definition method is what is used to create an instance of the Board class. Laravel comes with Faker, a library for generating fake data for testing.
In this application a board cannot exist without a user, so if an attempt at creating a board is made without a user then the database will throw a foreign key constraint error, preventing the Board entry to be created in the database. In the above example the user factory runs and creates a user, along with a tag as a board also cannot exist if there are no pre-existing tags. The title and description for the board are auto generated using the Faker library.
Using Factories
There are different ways a factory can be called, either using the php command line ( php artisan tinker ) or programatically, the latter will be covered later in this blog post when discussing seeding.
To create Board using the factory the Board class has a static method named factory.
The create method persists the model into the database, if you don't want the model persisted then replace create with make. Fields can be overridden and specified manually, as is shown in the second command that is displayed in the above example. The factory method can then be chained with multiple other methods like count, as shown above, which is a method that allows the developer to specify the number of instances to be created.
The configure Method
The configure method contained within the factory allows for extra functionality to be added to the factory. The applications database structure was covered previously in another blog entry ( which you can read here ). Each board can have zero, one or many columns however for testing we'd like to make sure that the board is populated properly with some columns automatically when we create a board. This functionality can be implemented in the configure method. Note : this doesn't mean that when a user creates a board it will come with columns automatically, its only for when the factory method is used.
The above image shows the BoardFactory classes configure method in the application. In this example when a board is created using the factory, the column factory will run and create 5 columns. Each column is using the ID of the board created to override the default board_id for that given column.
When the code in the above image is run in the php terminal ( tinker ) it will create 10 Boards and in total 10*5 columns ( 5 columns per board ). The same approach has been taken with the ColumnFactory as well, meaning that each column will have 5 tasks, however the code follows the same format and is repetitive. The applications Factories are setup in a way where if a User is created it will have 5 boards, each with 5 columns and each column having 5 tasks. This configuration provides an easy way to quickly populate the database for testing after a fresh migration.
Seeding The Database
Seeding the database is yet another thing that is made simple by Laravel and artisan. To start with a seeder class can be created using the command in the following image, followed by a name for the class. The convention is that it should be PascalCase and should have the word Seeder at the end, in this instance the name used is DatabaseSeeder which outputs the file
app_root / database / seeders / DatabaseSeeder.php. This class extends (and therefor) inherits a lot of methods from the Seeder base class, the method in this instance that is of importance however is the run method.
All of the hard work has been done already for seeding the database, it was done in the previous section by creating a factory for each model. Before the application can be used there must be records created in the tags table, otherwise users can register however they won't be able to create boards and use the core functionality of the application ( which will be covered in a later entry ).
The contents of the DatabaseSeeder.php file can be seen above ( the dependencies have been omitted ). There is an array of default tags the application will use, which are looped over and used in the Tag factory.
By running php artisan db:seed the DatabaseSeeder class will run its run method and populate the tags table with tags. If a seeder has been created specifically for creating Users then a different approach must be taken where the name of the seeder must be given to the command. In this application this approach wasn't taken as it wasn't necessary, more can be read on how to do this though by referring to the official Laravel docs.
Concluding Remarks
Creating, using and configuring factories is made easy by Laravel. The framework does a fantastic job of abstracting away the technicalities that the developer doesn't need to know, allowing for rapid testing and development of features. The artisan commands, yet again, assist the developer greatly by creating large amounts of scaffolding code that the developer can add to.








Comments
Post a Comment