Creating Your First Blog With TALL - Part Four
Tags: tailwindcss, laravel, alpinejs, livewire
Published: 2021-03-18 01:12:00

Welcome back to today's episode. You learnt everything about setting up your database: creating models, different approaches to running database queries and running migrations in the last episode. This episode builds on that by teaching you how to create database factories and seed our database tables with sample data we can use for our blog.

You should be able to learn the following at the end of this tutorial:

   - What model factories are.
   - How to create and write model factories.
   - What database seeders are.
   - How to create and write database seeders.
   - How to run database seeders in order to seed our blog's database with some sample data.

## Model Factories

Model factories in Laravel allow you to generate dummy/fake data using the [Faker](https://github.com/fzaninotto/Faker) PHP library. The Faker library allows generating random data by specifying various attributes. With factories you define fake data to be generated for each attribute/column of your model. This not only saves you time of manually inserting database records, but enables you to save thousands of records in your database within seconds.
### Creating Factories
Factories are created using the Laravel make:factory Artisan command, like so:
```
php artisan make:factory PostFactory
```
This creates the `PostFactory` factory in the **database/factories** folder with no model specified. To specify a model the factory belongs to, you can append the --model option to the above command. You can also create a factory when creating a new model with -f option and that model will eventually be created when the factory is run, as we did in the previous tutorial.

If you open the **database/factories/PostFactory.php** file you should notice the factory class definition is similar to this:
```
<?php

namespace Database\Factories;

use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            //
        ];
    }
}
```
A Laravel factory basically extends the base Factory class and defines two important members: a `$model` the factory will be creating and a `definition` method that defines the values to be applied when the factory is executed. The `$model` property will be automatically filled when you create the factory with the `make:factory` command by specifying the `--model` option and when you specify the `-f` option when creating a model.
### Writing Factories
Though our factory is created, we'll have to tell Laravel how we want our data to be generated when this factory is run. To do that, we have to define each attribute/column of the `Post` model/post table and its corresponding value as an associative array of key-value pairs in the `definition` method of our factory.

The base Laravel Factory class has a Faker instance and so each factory has access to this Faker instance. You generate values for each of your columns using this Faker instance. So, the definition for our `Post` model's attributes will look like below:
```
// tall-blog/database/factories/PostFactory.php
...
...
...
    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'category' => $this->faker->text(100),
            'body' => $this->faker->paragraphs(15, true),
            'title' => $this->faker->sentence(15),
            'excerpt' => $this->faker->sentences(3, true),
            'featured_image' => "post.png",
            'published_date' => $this->faker->date(),
            'user_id' => 1,
        ];
    }
```
You notice that we've "hard-coded" some values such as the `user_id` and the `featured_image` fields. This is because auto-generating these values will not be the best since they depend on other factors. We've also left out the `is_published` field since we provided a default `false` value for it and want a post to stay unpublished until we decide to publish it.

One thing we'd want to add to our factory is a published [state](https://laravel.com/docs/8.x/database-testing#factory-states). This can be used to modify the default value of the `is_published` column(which, by default, is `false`) whenever we want to make a particular post as published. Add this method at the end of the `PostFactory` class to do that:
```
// tall-blog/database/factories/PostFactory.php
...
...
... 
/**
     * Indicates the post is published.
     *
     * @return \Illuminate\Database\Eloquent\Factories\Factory
     */
    public function published()
    {
        return $this->state(function (array $attributes) {
            return [
                'is_published' => true,
                'published_date' => now(),
            ];
        });
    }
```
You see that this method uses the `state` method provided by the base factory class, which accepts a closure containing the attributes we defined for this factory in the `definition` method as argument and returns the attributes to modify. Here we're just changing the `is_published` column to `true` and providing the current date time as the published date.
### Using Factories
After creating and defining your factories, the next thing is to use them to create models. This can be achieved by using the `factory` method provided by the `HasFactory` trait we talked about in the previous episode like so:
```
//Creates a post without persisting to database
$post = Post::factory()->make();

// Same as above, but creates five(5) posts
$post = Post::factory()->count(5)->make();

// Same as above, but sets the published state to true
$post = Post::factory()->count(5)->published()->make()﻿;

//Creates a post and persists it to database
$post = Post::factory()->create();

// Same as persisting, but creates five(5) posts
$post = Post::factory()->count(5)->create();

// Same as persisting, but sets the published state to true
$post = Post::factory()->count(5)->published()->create()﻿;
```
## Database Seeders
While model factories let you create sample data for your models, database seeders actually insert these data into the database, though seeders don't necessarily have to depend on factories to insert data. This means you can either use factories to seed data into your database or manually utilize Eloquent and the Query Builder to do so.

Seeders are placed in the **database/seeders** directory of your Laravel installation and, by default, contain a single `run` method - which is called when the `db:seed` command is executed. By default, Laravel creates a `DatabaseSeeder` class for you out of the box. You can use this class to run other seeders by providing them to the `call` method. This allows you to properly organize and arrange your seeders in any order you desire and also helps you run many seeders at once.
### Creating Database Seeders
Just like other features of the Laravel framework, database seeders are created by running Artisan commands. You execute the `make:seeder` Artisan command and provide the name of the seeder to create, like so:
```
php artisan make:seeder PostSeeder
```
### Writing Database Seeders
As I already mentioned above, seeders, by default, contains a single `run` method that is executed when the `db:seed` command is run. In the `run` method you insert your data by manually running Eloquent queries or by using factories. We're using the latter for this tutorial.

To insert data, we're going to make use of the `PostFactory` we created in the previous sections. Within the `run` method put this:
```
// tall-blog/database/seeders/PostSeeder.php
...
...
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Post::factory()
                ->count(20)
                ->published()
                ->create();
    }
...
...
```
We're creating 20 records of the `Post` model into our database whilst specifying that each post's state must be published, as opposed to the default unpublished behavior.

The last thing we want to do is open the `DatabaseSeeder` class and add the `PostSeeder` class to the `call` method's arguments in the `run` method:
```
// tall-blog/database/seeders/DatabaseSeeder.php
...
...
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call([
            PostSeeder::class,
        ]);
    }
...
...
```
Though we could just run the `PostSeeder` without adding it here, doing it this way keeps your seeders organized and decoupled and can be run from a single central point.
### Running the Seeder
Now that our seeder and factory are defined, we can proceed to seed our database with sample data. As pointed out already, seeders are run using the `db:seed` command and optionally providing the `--class` option, which is used to specify the seeder class we want to run:
```
php artisan db:seed
```
I didn't provide the `--class` option because Laravel runs the `DatabaseSeeder` class by default if it is not provided. Running the above will produce an output such as this:
```
kamil@kamil-sc650:~/Projects/Web/tall-blog$ php artisan db:seed
Seeding: Database\Seeders\PostSeeder
Seeded: Database\Seeders\PostSeeder (3,633.28ms)
Database seeding completed successfully.
```
Check your database to see the posts table filled with 20 posts.

This brings us to the end of the fourth episode of Creating Your First Blog With TALL tutorial series. Our next episode will teach you how to create and write your first Livewire components. See you then.