Creating Seed Data

Steps in creating a new seed data file

Adding new seed data is as simple as creating a new PHP file with a name matching the entity's name.

Using PortfolioArtifact model as an example, the file name should be PortfolioArtifactsSeedData.php

Creating Seed Data classes

When creating a new seed data class, extend the SeedData abstract class. There are two abstract classes that can be used, SeedData and RawSeedData.

The seed generator is looking for the data() method to populate the database using the returned array.

RawSeedData abstract class

For RawSeedData, the $table property must be set to the name of the database table.

abstract class RawSeedData implements RawSeedDataInterface
{
    ...
    /**
     * @var string The database table name
     */
    protected string $table;
    
    ...
}

SeedData abstract class

The SeedData class uses an Eloquent model to determine the table structure.

abstract class SeedData implements SeedDataProvider
{
    /**
     * Get the class name of the Eloquent model
     *
     * @return string
     */
    abstract public function type(): string;
}

Implement the type() method in the seed data class to return the model class name.

Example from RawSeedData

class CommunityPagesSeedData extends RawSeedData
{
    /**
     * @var string The database table name
     */
    protected string $table = 'community_pages';

    /**
     * Get the community pages list
     *
     * @return array
     */
    public static function getCommunityPages(): array
    {
        return [
            [
                'cpage_id' => 1,
                'community_id' => 1,
                'parent_id' => 0,
                'page_order' => 0,
                'page_type' => 'default',
                'menu_title' => 'Home',
                'page_title' => 'Home',
                'page_url' => '',
                'page_content' => '',
                'copied_from' => 0,
                'page_active' => 1,
                'page_visible' => 1,
                'allow_member_view' => 1,
                'allow_troll_view' => 1,
                'allow_public_view' => 1,
                'updated_date' => Carbon::create("Thu Dec 02 2021")->timestamp,
                'updated_by' => 1,
            ],
        ];
    }

    /**
     * Get the raw seed data
     *
     * @return array
     */
    public function data(): array
    {
        return self::getCommunityPages();
    }
}

Using the Carbon library to generate timestamps makes the timestamp easier to read (i.e. instead of using UNIX integer timestamps).

A value is needed for every column in the table when using the RawSeedData.

Example extending SeedData

class CommunityPagesSeedData extends SeedData
{
    /**
     * Get the community pages list
     *
     * @return array
     */
    public static function getCommunityPages(): array
    {
        return [
            [
                'cpage_id' => 1,
                'community_id' => 1,
                'parent_id' => 0,
                'page_order' => 0,
                'page_type' => 'default',
                'menu_title' => 'Home',
                'page_title' => 'Home',
                'page_url' => '',
                'page_content' => '',
                'copied_from' => 0,
                'page_active' => 1,
                'page_visible' => 1,
                'allow_member_view' => 1,
                'allow_troll_view' => 1,
                'allow_public_view' => 1,
                'updated_date' => Carbon::create("Thu Dec 02 2021")->timestamp,
                'updated_by' => 1,
            ],
        ];
    }

    /**
     * Get the raw seed data
     *
     * @return array
     */
    public function data(): array
    {
        return self::getCommunityPages();
    }

    /**
     * Get the Eloquent model type
     *
     * @return string
     */
    public function type(): string
    {
        return CommunityPages::class;
    }

}

When extending SeedData instead of RawSeedData, extra records may be created if an event gets fired every time the model in the seed data class is created. For example, if the model class has additional code in it's boot() method, then it may create additional records that could conflict with other seed data files. These will not be created if RawSeedData is used instead.

When creating seed data that contains an ID which will be used in multiple locations, create a const for readability.

Example STUDENT_PROXY_ID contains the ID of a user that has a role of student

Updating/Adding a Seeder File

After creating a new seed data class, the seeds() method in the module's corresponding seeder class must be updated. Every module should have a seeder class located in the following path:

app/Modules/{MODULE_NAME}/Database/Seeds

This file's name should match the module name suffixed with Seeder. For example, the Absences module seeder class file would be:

app/Modules/Absences/Database/Seeds/AbsencesSeeder.php

- app
  - Modules
    - Absences
      - Database
	- Seeds
	  - Data
	    - AbsencesSeedData.php
	 - AbsencesSeeder.php

This seeder class is responsible for importing and initializing all the seed data classes that belong to that module.

If the module doesn't already have a seeder file, create one using the snippet below and other seeder files as an example.

namespace Entrada\Modules\{MODULE_NAME}\Database\Seeds;

use Entrada\Modules\{MODULE_NAME}\Database\Seeds\Data;
use Entrada\Support\Database\Seeder;

class {MODULE_NAME}Seeder extends Seeder
{
    public function seeds(): array
    {
        return [
            new Data\{SEED_DATA_CLASS_NAME}(),
        ];
    }
}
  • Replace {MODULE_NAME} with the modules name

  • Replace {SEED_DATA_CLASS_NAME} with the seed data class name

Registering seeder class

This step is only necessary if you create a new module’s Seeder that didn’t exist before. Once you create a new Seeder, update the module database service provider i.e. app/Modules/{MODULE_NAME}/Providers/DatabaseServiceProvider.php to include the new seeder.

Example

<?php

namespace Entrada\Modules\{MODULE_NAME}\Providers;

use Entrada\Modules\{MODULE_NAME}\Database\Seeds\{MODULE_NAME}Seeder;
use Entrada\Support\Providers\DatabaseServiceProvider as ServiceProvider;

class DatabaseServiceProvider extends ServiceProvider
{
    /**
     * @var array Registered seeders
     */
    protected array $seeders = [
        '{MODULE_NAME}' => [{MODULE_NAME}Seeder::class],
    ];
}

Replace {MODULE_NAME} with the module's name.

Registering the database service provider

To register the database service provider, add it to the module service provider (if this was not done already).

Example

class ModuleServiceProvider extends ServiceProvider
{
   /**
   * Register the module services.
   *
   * @return void
   */
   public function register()
   {
      $this->app->register(DatabaseServiceProvider::class);
      ...

Defining timestamps in Seed Data

If seed data needs to include a timestamp relative to today's date, then Laravel's Carbon class should be used.

 Carbon::now()->getTimestamp()

Carbon can also be used to create a timestamp from a date string.

$newYear = Carbon::create('first day of January 2016');
// DateTime example
$updated_date = Carbon::create("Dec 09 2019 00:00:00"); // or 
$updated_date = Carbon::create("2019-12-09 00:00:00")
// Date example
$updated_date = Carbon::create("Dec 09 2019");

Use timestamp property of Carbon objects to store the actual timestamp in seed data records.

class EventAttendanceSeedData extends RawSeedData
    // ...
    public function data(): array
    {
        return [
            [
                'eattendance_id'    => 1,
                'event_id'          => 2,
                'proxy_id'          => 3,
                'active'            => 1,
                'comments'          => null,
                'update_method'     => null,
                'ea_status_id'      => 2,
                'updated_date'      => Carbon::now()->timestamp,
                'updated_by'        => 1,
                'attendance_time'   => Carbon::now()->timestamp,
            ]
        ];
    }
}

Official Carbon documentation

Article on using Carbon

Last updated