CRUD app using Laravel 8 VILT stack (Part 1)

(Note: This article has been updated with Breeze starter kit in place of Jetstream.)

In this tutorial we’ll learn the steps needed to set up basic CRUD app using VILT stack. VILT stands for Vue, Inertiajs, Laravel and Tailwind. VILT stack is an emerging web stack presenting the opportunity to develop a web app using robust modern open source technologies. So, let’s start our classic CRUD app using VILT stack.

Assuming that the composer is installed, enter the following command to create new Laravel project:

composer create-project laravel/laravel app 8.*

Now go inside the newly created app folder

cd app

Enter following command to add Breeze package:

composer require laravel/breeze:1.9.2

Now install Breeze with Vue and Inertia capability by entering following command:

php artisan breeze:install vue

Assuming node.js and npm are installed, enter the following command to install required node modules:

npm install

Next, setup database and Laravel environment file as usual. Here, I’m configuring SQLite database for simplicity purposes. Enter following command to create empty SQLite database:

touch database/database.sqlite

Edit .env file as follows:

DB_CONNECTION = sqlite

You can remove DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD from .env when using SQLite database.

Since, initial setup of Laravel app is complete, we can start building our CRUD. First enter the following command to create Post model along with the migration:

php artisan make:model Post -m

Open newly created migration file from database/migrations/ which is named something like (datestamp)_create_posts_table.php and then insert the desired table fields e.g.

<?php

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

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');

            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Enter following command to migrate the above migration:

php artisan migrate

Since our database part is done for the time being; let’s move onto model and controller. First, amend the Post model by inserting fillable array into the model. For that, open app/Models/Post.php and insert protected fillable array as follows:

<?php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title', 'body'
    ];
}

Having done with the Model part of our app, we move onto Controller part by creating new PostController as follows:

php artisan make:controller PostController

This command will create PostController.php. Go ahead and open this file located at app/Http/Controllers/PostController.php and amend it as follows:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request;
use Inertia\Inertia;
use App\Models\Post;

class PostController extends Controller
{

    public function index()
    {
        $data = Post::all();
        return Inertia::render('Posts/Index', ['data' => $data]);
    }

    public function create()
    {
        return Inertia::render('Posts/Create');
    }

    public function store()
    {
        Post::create(
            Request::validate([
            'title' => ['required', 'max:50'],
            'body' => ['required'],
            ])
        );
        return Redirect::route('posts')->with('success', 'Post created.');
    }

    public function show(Post $post)
    {
    }

    public function edit(Post $post)
    {
        return Inertia::render('Posts/Edit', [
            'post' => [
                'id' => $post->id,
                'title' => $post->title,
                'body' => $post->body,
            ],
        ]);
    }

    public function update(Post $post)
    {
        $post->update(
            Request::validate([
            'title' => ['required', 'max:50'],
            'body' => ['required'],
            ])
        );

        return Redirect::route('posts')->with('success', 'Post updated.');
    }

    public function destroy(Post $post)
    {
        $post->delete();
        return Redirect::back()->with('success', 'Post deleted.');
    }

}

Finally, open routes/web.php and put the following line at the top of it:

use App\Http\Controllers\PostController;

And then insert following CRUD routes into this web.php:

Route::get('posts', [PostController::class, 'index'])
    ->name('posts')
    ->middleware('auth');

Route::get('posts/create', [PostController::class, 'create'])
    ->name('posts.create')
    ->middleware('auth');

Route::get('posts/{post}', [PostController::class, 'show'])
    ->name('posts.show')
    ->middleware('auth');

Route::post('posts', [PostController::class, 'store'])
    ->name('posts.store')
    ->middleware('auth');

Route::get('posts/{post}/edit', [PostController::class, 'edit'])
    ->name('posts.edit')
    ->middleware('auth');

Route::put('posts/{post}', [PostController::class, 'update'])
    ->name('posts.update')
    ->middleware('auth');

Route::delete('posts/{post}', [PostController::class, 'destroy'])
    ->name('posts.destroy')
    ->middleware('auth');

For now we’re done with the ‘M’ and ‘C’ parts of our MVC (Model View Controller) app using VILT stack. In next part of this tutorial we’ll create views (‘V’ of MVC) for this app using vue.js coupled with inertia.js.

2 thoughts on “CRUD app using Laravel 8 VILT stack (Part 1)”

Leave a Comment