Creating Your First Blog With TALL - Part Three
Tags: laravel, tailwindcss, alpinejs, livewire
Published: 2021-03-13 02:01:00

Hello and welcome to the third episode of the **Creating Your First Blog With TALL** tutorial series. You learnt how to configure Jetstream, setup database connection, create routes, create a symlink and change the default Jetstream logo in the previous episode.

In this episode, you're going to learn how to setup and run migrations to create the tables for our blog and create the needed models for the project. At the end, you should be able to:

1.  Get a basic understanding of the alternative ways Laravel lets you run database queries.
2.  Know and explain what Laravel Eloquent models and migrations are.
3.  Create models and migrations for any Laravel project
4.  Run migrations for our project

Okay. Take a sip of coffee and let's dive in right away. :)

## The Alternative Ways Database Queries are Run in Laravel

If you're coming from the traditional way of developing web apps using plain PHP, you may be blown away by how much Laravel eases the pain of handling database operations. Think about having to manually write SQL queries, take care of SQL vulnerabilities like SQL injection, and many others that you'll have to deal with, all taken care of by the framework.

In Laravel, you not only have to not manually write SQL commands in your PHP code, you have several options on how you want to run your database queries, including what you're used to when developing using plain PHP (albeit in a very simplified, easier way). You can write Laravel database operations using either raw SQL, the Laravel [Query Builder](https://laravel.com/docs/8.x/queries) or [Eloquent](https://laravel.com/docs/8.x/eloquent#introduction) models. We'll only look at the latter two in this tutorial. You can learn more about running raw SQL queries [here](https://laravel.com/docs/8.x/database#running-queries).

### Using Query Builder to Run Database Queries

The Query Builder is a general and convenient way of creating and running database queries. It can be used to run most of the database query operations supported by your database driver through the [DB](https://laravel.com/api/5.8/Illuminate/Support/Facades/DB.html) facade. The `DB` facade provides a convenient `table` method you can use to run queries against a given table. Other methods of the `DB` facade such as [insert](https://laravel.com/docs/8.x/queries#insert-statements), [update](https://laravel.com/docs/8.x/queries#update-statements), [select](https://laravel.com/docs/8.x/queries#select-statements), [where](https://laravel.com/docs/8.x/queries#retrieving-a-single-row-column-from-a-table), [delete](https://laravel.com/docs/8.x/queries#delete-statements), [get](https://laravel.com/docs/8.x/queries#running-database-queries) etc can then be chained to the `table` method to run those respective queries like so:
```
use Illuminate\Support\Facades\DB;

// Select all users
$users = DB::table('users')->get();

// Select only approved users
$users = DB::table('users')->where('approved', true)->get();﻿

// Delete all users
DB::table('users')->delete();

// Insert a new user
DB::table('users')->insert([
    'username' => 'awesomeuser',
    'email' => 'awesomeuser@example.com'﻿
]);﻿﻿

// Update an existing user
$userAffected = DB::table('users')
              ->where('id', 2)
              ->update(['username' => 'mynewawesomename']);
```
  

### Using Eloquent to Run Database Queries

Laravel Eloquent is an [Object-Relational Mapper](https://en.wikipedia.org/wiki/Object-relational_mapping) (ORM) that enables you to run database queries using models. Models allow you to store data and handles the logic that goes with it. With Eloquent, each table has a corresponding model class that deals with querying and storing data in that table. Since the rest of this tutorial will entirely be on using Eloquent, I'll leave explanation of Eloquent models here and continue with the other sections.

## Creating Eloquent Models and Migrations

### Eloquent Models

As I pointed out above, Eloquent models help you to store data and its related logic. Models act like data warehouse operators - any data entering/leaving the warehouse goes through them, they keep track of and update records, they can filter and sort items out, they know how to sanitize and check data for integrity and so much more.

### Database Migrations

The Laravel docs does so well in explaining what migrations are and I won't repeat myself here. This is what the docs say about migrations:

> Migrations are like version control for your database, allowing your team to define and share the application's database schema definition. If you have ever had to tell a teammate to manually add a column to their local database schema after pulling in your changes from source control, you've faced the problem that database migrations solve.

### How to Create Eloquent Models

Like many other Laravel features, you can create Eloquent models by running [Artisan commands](https://laravel.com/docs/8.x/artisan) from the terminal. To create a model, use the `make:model` command like so:
```
php artisan make:model ModelName
```
Where `ModelName` is the actual name of the model you want to create. This creates the given model (which extends `\Illuminate\Database\Eloquent\Model`) in the **app\Models** directory. You can optionally pass `-m`, `-c`, `-f`, `-s` to respectively create a [migration](https://laravel.com/docs/8.x/migrations#introduction), [controller](https://laravel.com/docs/8.x/controllers), [factory](https://laravel.com/docs/8.x/database-testing#defining-model-factories) or a [database seeder](https://laravel.com/docs/8.x/seeding)(we'll explain these later in the coming series) in addition to the given model, or even combine these options, like so:
```
php artisan make:model ModelName -m // creates migration too
php artisan make:model ModelName -c // creates controller too
php artisan make:model ModelName -f // also creates a factory
php artisan make:model ModelName -s // also creates a database seeder
php artisan make:model ModelName -mfcs // creates migration, factory, controller and seeder
```
### How to Create Migrations

Migrations are created by running the `make:migration` Artisan command, passing the name of the migration and an optional `--path` argument to specify where the migration should be placed. So creating a migration for `ModelName` above will look like below:
```
php artisan make:migration create_model_names_table
```
This will create a **create_model_names_table** migration in the **database/migrations** directory with two methods: `up` and `down`. `up` is used to add tables, indices and columns while `down` reverses these actions. For an in-depth understanding of migrations and models, please consult the official [docs](https://laravel.com/docs/8.x/).

### Creating Models and Migrations for Our Blog

Now that you have learnt what models and migrations are and how to create them, lets move on to create the models and migrations our blog will need. Because this is an introductory tutorial, our blog will only have one `Post` model in addition to the built-in `User` model (in a real world blog you'll definitely want to add other models such as category and tag models, but we don't wanna make this tutorial complicated and so we'll keep things as simple as possible.). And because there is a relationship between a blog post and the user who wrote it, we'll have to establish a database relationship here.

In any blogging system, a blog post belongs to a particular user. A user can have as many blog posts as they choose to. In this case of ours, a blog post cannot belong to multiple users, so we have a one-to-many relationship between users and posts. Laravel supports different kinds of entity relationships and one-to-many is just one of them we'll use in this tutorial.

To define the relationship a user has on posts, open the **app/Models/User.php** file and add this method to the end of it:
```
// tall-blog/app/Models/User.php
...
...
...
/**
* Get the posts for this user
*/
public function posts() {
    return $this->hasMany(Post::class);
}
...
```
This creates a one-to-many relationship to the `Post` model and allows us to get a user's posts by calling `$user->posts` on an existing `$user` object. If you see errors that the `Post` class doesn't exist just ignore it since that's what we're going to create next.

Create the `Post` model by running the `make:model` command and by specifying the `-m`, `-s`, and `-f` options:
```
php artisan make:model Post -mfs
```
This will create the `Post` model in **app/Models**. In addition, a new migration will be created in the **database/migrations** directory, a new model factory in **database/factories** and a database seeder in **database/seeders**.

Open the `app/Models/Post.php` model file and make sure its contents is exactly as follows:
```
// tall-blog/app/Models/Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model {
    use HasFactory;

    /**
     * Columns that are mass assignable
     */
    protected $fillable = [
        'title', 'excerpt', 'body', 'category',
        'featured_image', 'published_date',
        'is_published', 'user_id'
    ];

    /**
     * Returns the user for this post
     */
    public function user() {
        return $this->belongsTo(User::class)->withDefault();
    }
}
```
First of all, we're importing the `HasFactory` facade and the base Model class. Using the `HasFactory` facade here means the `Post` class has access to the `factory` method of the `HasFactory` facade, which is used to create factories. Our `Post` class extends the base `Model` class, which every model extends and therefore, will inherit all the methods available in the `Model` class. We have also defined the `$fillable` array property of the base `Model` class, which lists the attributes of the `Post` model that are [mass assignable](https://laravel.com/docs/8.x/eloquent#mass-assignment). Remember these attributes are also the columns for our posts table.

Lastly, we have defined a [reverse one-to-many relationship](https://laravel.com/docs/8.x/eloquent-relationships#one-to-many-inverse) between a post and its owner - a user. Just like the one-to-many relationship we defined for the `User` model, adding the reverse relationship this way enables us to query an existing `Post` object's user by simply calling `$post->user`.

* * *

We already learnt how to create migrations and we have even created the **create_posts_table** migration above when we run the `make:model` with the `-m` option specified. As I mentioned already, this migration is located in the **database/migrations** directory. Open it(Laravel prepends the current date to a migration's name when you create it, so you'd have to consider that when you're looking for the migration) and ensure the `up` method looks exactly as below:
```
// tall-blog/database/migrations/2021_03_10_141045_create_posts_table.php 
/**
 * Run the migrations.
 *
 * @return void
*/
public function up() {
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('category');
        $table->string('excerpt');
        $table->longText('body');
        $table->string('title');
        $table->boolean('is_published')->default(false);
        $table->string('featured_image');
        $table->dateTime('published_date');
        $table->foreignId('user_id')->constrained();
        $table->timestamps();
    });
}
```
All we're doing here is creating the '**posts**' table using the `create` method from the `Schema` facade. This method accepts the table to create as the first argument and a closure that uses the given `Blueprint` to define columns for the table. Ignoring all the column types (which you can learn [here](https://laravel.com/docs/8.x/migrations#available-column-types)), we're also specifying an auto-incrementing ID column(from `$table->id()`) for our table, a foreign ID constraint that references the **'users'** table at the database level(from `$table->foreignId('user_id')->constrained()`), and a timestamps columns (from `$table->timestamps()`) that will automatically create a **created\_at** and **updated\_at** columns for us.

Save the file. Ensure your database server is running and run the migrations to create the posts table:
```
php artisan migrate
```
If everything went well, you should get an output such as this:
```
kamil@kamil-sc650:~/Projects/Web/tall-blog$ php artisan migrate
Migrating: 2020_05_21_100000_create_teams_table
Migrated: 2020_05_21_100000_create_teams_table (3,058.26ms)
Migrating: 2020_05_21_200000_create_team_user_table
Migrated: 2020_05_21_200000_create_team_user_table (1,294.05ms)
Migrating: 2020_05_21_300000_create_team_invitations_table
Migrated: 2020_05_21_300000_create_team_invitations_table (3,464.26ms)
Migrating: 2021_03_10_141045_create_posts_table
Migrated: 2021_03_10_141045_create_posts_table (3,663.84ms)
```
You can check to see the created tables in the `tall_blog` database by using the terminal client for your database server or a GUI program such as [phpMyAdmin](https://www.phpmyadmin.net/), if you're using MySQL.

This brings us to the end of this episode of the **Creating Your First Blog With TALL** tutorial series and I hope you enjoyed the tutorial. In the next episode, you'll learn how to create model factories and database seeders in order to fill our database with sample data.

See you for the next post.