Beginner’s Guide to Laravel: Model View Controller Architecture

Introduction

In the world of web development, maintaining clean and organized code is essential for building scalable and maintainable applications. Laravel provides developers with a powerful architectural pattern called MVC (Model-View-Controller) to achieve this goal. In this tutorial, we will walk you through the process of building a web application using Laravel's MVC architecture, focusing on creating a "Book" model as an example.

Understanding MVC Architecture

MVC (Model-View-Controller) is a software architectural pattern that separates an application into three distinct components: Model, View, and Controller. The Model represents the data and business logic, the View handles the presentation and user interface, and the Controller manages the interaction between the Model and View.

Setting Up Laravel

Before we begin, ensure you have Laravel installed. If not, follow my Laravel installation guide (link) to get started.

Creating the Book Model

In Laravel, a model represents the data and business logic of your application. It interacts with your database, performing tasks such as querying, inserting, updating, and deleting records. Each model typically corresponds to a database table. To create a model in Laravel, you can use the artisan command-line tool:

php artisan make:model Book

This command will generate a model file under the app directory. Let's dive into the Book model file (app/Book.php) and break down its key components in Laravel.

Defining the Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    protected $fillable = ['title', 'author', 'published_year'];
}

Here's an explanation of the key components of the Book model:

  1. Namespace Declaration (namespace App;)

Namespaces help organize your code and prevent naming conflicts. In this case, the Book model is placed within the App namespace, which is the default namespace for Laravel models.

  1. Class Declaration (class Book extends Model)

The Book class extends Laravel's base Model class. This inheritance provides the Book model with various methods and properties for interacting with the database.

  1. Specifying Fillable Attributes

Define the fillable attributes using the $fillable property. This protects against mass assignment vulnerabilities.

protected $fillable = ['title', 'author', 'published_year'];
  1. Table Name Inference

By convention, Laravel assumes that the table corresponding to the Book model is named books, following the plural form of the model name. If your table name is different, you can explicitly set it in the model using the $table property:

protected $table = 'my_books_table';
  1. Timestamps (public $timestamps = true;)

By default, Laravel assumes that your database table has created_at and updated_at timestamp columns to track when records were created and last updated. If your table doesn't have these columns, you can disable timestamps by setting $timestamps to false.

  1. Date Format (protected $dateFormat = 'Y-m-d H:i:s';)

This property specifies the format in which dates should be stored in the database and returned as attributes of the model. The default format is Y-m-d H:i:s (year-month-day hour:minute:second). You can customize this format if needed.

These key components help define the behavior and attributes of the Book model in Laravel. You can extend this model by adding custom methods, relationships, and other attributes based on your application's requirements. The model serves as an interface between your application's data and the underlying database, allowing you to perform various operations on the data using Laravel's built-in features.

Designing Views

The view is responsible for presenting the data to the user. It defines the user interface and how data is displayed. Laravel's Blade templating engine makes it easy to create dynamic and reusable views. Views are typically stored in the resources/views directory. For our book model, we need to create views to display the list of books and provide forms for adding and editing books. For simplicity, we'll create a basic example for displaying all the books in the database.

Displaying a List of Books

Create a directory named books in the resources/views/books directory, and then create a view file named index.blade.php with the following contents:

<!-- resources/views/books/index.blade.php -->
<!DOCTYPE html>
<html>
<head>
    <title>Book List</title>
    <!-- Include Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container mt-5">
        <h1 class="mb-4">Books</h1>
        <ul class="list-group">
            @foreach($books as $book)
                <li class="list-group-item d-flex justify-content-between align-items-center">
                    <div>
                        <strong>{{ $book->title }}</strong><br>
                        <span class="text-muted">Published: {{ $book->published_year }}</span>
                    </div>
                    <div>
                        <!-- Add edit and delete links/buttons here -->
                    </div>
                </li>
            @endforeach
        </ul>
    </div>
    <!-- Include Bootstrap JS (optional) -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

Building the Controller

The controller acts as an intermediary between the model and the view. It receives requests from the user, processes the input, interacts with the model to retrieve or manipulate data, and then passes the data to the appropriate view for rendering. Controllers are typically stored in the app/Http/Controllers directory.

Creating a Controller

You can create a controller that will handle CRUD (Create, Read, Update, Delete) operations for the Book model:

php artisan make:controller BookController

Implementing Controller Methods

Open the generated BookController.php file (app/Http/Controllers/BookController.php) and add the necessary methods:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Book;

class BookController extends Controller
{
    public function index()
    {
        $books = Book::all();
        return view('books.index', compact('books'));
    }

    // Other CRUD methods (create, edit, update, delete) will be added here
}

The code above retrieves all the books from the Book model and returns the view we created above, having compacted the books inside. When we access this view, we should be able to view all the books in the system.

Configuring Routes

Routes are the entry points to your application's functionality, allowing users to access different pages and perform various actions. In this section, we'll explain the process of configuring routes in depth. Routes are defined in the routes/web.php file of your Laravel application. Open this file to define the routes that will determine how users interact with your application.

A basic route definition consists of an HTTP verb (GET, POST, PUT, DELETE, etc.), a URL path, and a callback function or controller method that handles the request. Here's an example of a route definition for the books url we are trying to access:

// routes/web.php
use App\Http\Controllers\BookController;

Route::get('/books', [BookController::class, 'index']);

In this example:

  • Route::get specifies a GET request.

  • /books is the URL path that users will visit.

  • 'BookController@index' refers to the index method in the BookController class that will handle the request. We have already defined this method above.

Running Migrations

Migrations in Laravel are represented as PHP files stored in the database/migrations directory. These files define the changes you want to make to the database schema. Here's an example of a migration file that creates a books table:

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

class CreateBooksTable extends Migration
{
    public function up()
    {
        Schema::create('books', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('author');
            $table->year('published_year');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('books');
    }
}

To apply the changes defined in migration files to the database, you use the migrate Artisan command. Open your terminal and run:

php artisan migrate

Laravel will execute the up method of each migration file that hasn't been run before, creating the corresponding database tables and columns. So, we have defined our table but if you’ve noticed, there is still one problem left. Our database has no data! Not to worry, this is where seeding comes in.

Seeding the Database

Seeding in Laravel is the process of populating your database with sample or initial data. This is especially useful for testing and setting up your application's database with predefined data. To seed the Book model, you'll need to create a seeder class and define the data you want to insert. Here's a step-by-step guide on how to seed the Book model:

  1. Create a Seeder Class

Laravel provides an Artisan command to create a new seeder class. Open your terminal and run:

php artisan make:seeder BookSeeder

This will create a new seeder class named BookSeeder in the database/seeders directory.

  1. Edit the Seeder Class

Open the newly created BookSeeder.php file and define the data you want to insert into the books table. You can use Laravel's Eloquent ORM to create and insert records.

// database/seeders/BookSeeder.php

use Illuminate\Database\Seeder;
use App\Book;

class BookSeeder extends Seeder
{
    public function run()
    {
        Book::create([
            'title' => 'Sample Book 1',
            'author' => 'John Doe',
            'published_year' => 2020,
        ]);

        Book::create([
            'title' => 'Sample Book 2',
            'author' => 'Jane Smith',
            'published_year' => 2018,
        ]);

        // Add more sample book records here...
    }
}
  1. Run the Seeder

To execute the seeder and insert the sample data, run the following command:

php artisan db:seed --class=BookSeeder

This command will run the run method of the BookSeeder class and populate the books table with the defined sample data.

Run the Application

Start the Laravel development server:

php artisan serve

Visit http://127.0.0.1:8000/books in your web browser to see the list of books.

Bringing it All Together

This example demonstrates the basic implementation of the MVC architecture in Laravel using a "Book" model. You can extend this example by adding more controller methods for CRUD operations, implementing forms for creating and updating books, adding validation, and enhancing the user interface

Conclusion

In this tutorial, we've explored the foundational concepts of Laravel's MVC architecture by creating a Book model, building a controller, designing views, and configuring routes. By following this guide, you've gained a solid understanding of how to structure your web applications for improved organization and maintainability using Laravel's powerful MVC pattern.

Remember, this tutorial only scratches the surface of what you can achieve with Laravel's MVC architecture. As you continue your journey in web development, you'll discover even more ways to leverage this pattern for creating feature-rich and efficient applications. See you in the next post!