DEV Community

Nelson Orina
Nelson Orina

Posted on

Laravel Models, Migrations, & Relationships: Setting Up The 'Post' Feature

Welcome back! With secure user authentication in place, we can now focus on building the core functionality of our blog: creating and managing posts. This post will walk you through setting up a new Eloquent Model and its corresponding database table, and establishing the crucial one-to-many relationship between a user and their posts.

What We'll Cover Today

  • Generating the Post Model and Migration file.
  • Defining the necessary database columns for our posts.
  • Understanding and setting up the one-to-many relationship between User and Post.
  • Configure the Post model's $fillable property for mass assignment.

Step 1:Generating the Post Model and Migration

Just as the User model connects our application to the users table, we need a Post Model to interact with a future posts table. Laravel provides a powerful Artisan command to generate both files simultaneously.

1.The Artisan Command

Open your terminal in your project's root directory and run:

php artisan make:model Post -m 
Enter fullscreen mode Exit fullscreen mode

2.Verification

You should now have two new files:

  • Model: app/Models/Post.php
  • Migration: database/migrations/YYYY_MM_DD_HHMMSS_create_posts_table.php (The timestamp ensures migrations run in the correct order).

Step 2:Defining the posts Database Structure

The migration file is where we design the structure of our posts table. A blog post needs several key columns, including the content and, critically, a way to link it back to the user who created it.

1.Update the Migration File

Open the new migration file(...create_posts_table.php) and modify the up() method to look like this:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->string('title');
            $table->longText('body');
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

Enter fullscreen mode Exit fullscreen mode

2.Key Columns Explained

  • $table->id():The primary key, a unique auto-incrementing identifier for the post.
  • $table->foreignId('user_id'):This is the Foreign Key. It's the critical link to the users table. It will store the id of the user who owns this post.
  • ->constrained():A shortcut that tells Laravel this user_id column references the id column on the plural form of the table(users).
  • onDelete('cascade'):This is a powerful database-level rule. If a user is deleted, all of their associated posts will also be automatically deleted.This ensures data integrity.
  • $table->string('title'): A simple string column for the post's title.
  • $table->text('body'): A larger text column suitable for the main content of a blog post.

Step 3:Running the Migration

Now that the structure is defined, we run the same command from our previous post to create the actual table in the database.

1.The Command

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

2.Verification

Check your database with a management tool (like HeidiSQL). You should now see a new table named posts with the columns we defined, including the user_id foreign key.

Step 4: Configuring the Post Model

With the table created, we configure the Post.php model to safely interact with the database, just as we did for the User model.

1.Set the $fillable Property

Open app/Models/Post.php and add the $fillable property. This protects against unexpected mass assignment by explicitly defining which fields can be filled in a single Post::create([...]) command.

// app/Models/Post.php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory;

    // Define the columns that can be mass-assigned
    protected $fillable = [
        'user_id',
        'title',
        'body',
    ];
}
Enter fullscreen mode Exit fullscreen mode

Step 5:Establishing the Eloquent Relationship

This is the most crucial step for a working blog application. We need to tell Laravel that a single user can have multiple posts, and a post belongs to only one user.

1. The user Model: One-to-Many(Has Many)

A user can have many posts. We define a relationship method named posts in the User model.

// app/Models/User.php

// ... other properties and methods

class User extends Authenticatable
{
    // ... other properties

    /**
     * Get the posts for the user.
     */
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}
Enter fullscreen mode Exit fullscreen mode
  • The Benefit: Now, you can retrieve all posts by a user like this: $user->posts.

2. The Post Model:Inverse of One-to-Many(Belongs To)

A single post belongs to one user. We define a relationship method named user in the Post model.

// app/Models/Post.php

// ... other properties and methods

class Post extends Model
{
    // ... $fillable property

    /**
     * Get the user that owns the post.
     */

 public function user()
    {
        return $this->belongsTo(User::class);
    }
}
Enter fullscreen mode Exit fullscreen mode
  • The Benefit: Now, you can retrieve the author of any post like this: $post->user.

Wrapping Up: What We've Accomplished

  1. We created the Post Model and a new posts table with the essential user_id foreign key.
  2. We secured the model using the $fillable property.
  3. We established the powerful, two-way, one-to-many relationship between User and Post using Eloquent methods (hasMany and belongsTo).

In the next post, we will use this foundation to build the Post Creation Controller and the Blade Forms to finally let our users add content to the blog.

Top comments (0)