Overview
- Part 1: Walk-through installing and configuring Laravel
- Part 2: Create the core models/tables, controllers, and views
- Part 3: Authorization/Login
- Part 4: Post CRUD
- Part 5: Comment CRUD
- Part 6: Validation
- Part 7: Testing
Add MySQL tables
Posts and Comments
We're going to add migration files that create the MySQL tables.
./vendor/bin/sail artisan make:migration posts ./vendor/bin/sail artisan make:migration comments
# database/migrations/2021_06_23_155553_posts.php <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class Posts extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('user_id'); $table->foreign('user_id') ->references('id')->on('users') ->onDelete('cascade'); $table->string('title')->unique(); $table->text('body'); $table->text('metaDescription'); $table->string('metaTitle'); $table->string('slug')->unique(); $table->boolean('active'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('posts'); } }
# database/migrations/2021_06_23_155557_comments.php <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class Comments extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('comments', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('post_id'); $table->unsignedBigInteger('user_id'); $table->foreign('post_id') ->references('id')->on('posts') ->onDelete('cascade'); $table->foreign('user_id') ->references('id')->on('users') ->onDelete('cascade'); $table->text('comment'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('comments'); } }
Users
Adjust the standard user migration to add a new columnn to track the user's role
.
# database/migrations/2014_10_12_000000_create_users_table.php $table->enum('role',['admin','author','user'])->default('author');
Run the Migrations
./vendor/bin/sail artisan migrate
Make the models
Make the Post
and Comment
model + adjust the User
model to fetch the linked posts or comments.
./vendor/bin/sail artisan make:model Post ./vendor/bin/sail artisan make:model Comment
# 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; /** * Get the comments made on the post * * @return array App\Models\Comment */ public function comments() { return $this->hasMany('App\Models\Comment', 'post_id'); } /** * Get the user who created the post * * @return App\Models\User */ public function author() { return $this->belongsTo('App\Models\User', 'user_id'); } }
<?php # app/Models/Comment.php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Comment extends Model { use HasFactory; /** * The user who wrote the comment * * @return App\Models\User */ public function author() { return $this->belongsTo('App\Models\User', 'user_id'); } /** * The post the comment is associated with * * @return App\Models\Post */ public function post() { return $this->belongsTo('App\Models\Posts', 'post_id'); } }
Add these to the existing User model.
# app/Models/User.php public function posts() { return $this->hasMany('App\Models\Posts', 'user_id'); } public function comments() { return $this->hasMany('App\Models\Comments', 'user_id'); }
View/Layout
Add the base template to get a shared HTML structure started.
mkdir resources/views/layouts
Copy the welcome blade file and adjust it to include a @yield('content')
where you want the content to show up and @yield('title')
where you want the page title to show up.
cp resources/views/welcome.blade.php resources/views/layouts/app.blade.php
Add Post controller, view, and route
./vendor/bin/sail artisan make:controller PostController mkdir resources/views/blog/
Add the PostController
, it will fetch all active posts.
<?php # app/Http/Controllers/PostController.php namespace App\Http\Controllers; use Illuminate\Support\Str; use Illuminate\Http\Request; use App\Models\Post; class PostController extends Controller { public function index() { $posts = Post::where('active', 1) ->orderBy('created_at','desc') ->get(); //return blog.blade.php template from resources/views folder return view('blog.index', ['posts' => $posts, 'title' => 'Blog Posts']); } }
# resources/views/layouts/app.blade.php <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{ $title }}</title> </head> <body> @yield('content') </body> </html>
# resources/views/blog/index.blade.php @extends('layouts.app') @section('content') <h1>{{$title}}</h1> @forelse ($posts as $post) <li>{{ $post->title }}</li> @empty <p>No posts</p> @endforelse @stop
Add the route to send the URI /blog
to the controller
# routes/web.php Route::get('/blog', 'App\Http\Controllers\PostController@index');
Test it out
Load the /blog
path in the browser and confirm it works. http://localhost:6001/blog. You should see the title of Blog Posts
and No posts
because we haven't added anything yet.
Roundup
That's it for now. Part 3 will go through setting up a login mechanism and handling authorization.
Next: Authorization/Login