Laravel Eloquent Tutorial: Definitive Guide (2023)

by Solomon Eseme

.

Updated Thu Jul 06 2023

Laravel Eloquent Tutorial: Definitive Guide (2023)

Eloquent is one of the reasons behind Laravel’s success. As a backend developer, working with databases is your core responsibility, and in Laravel, the hassle has been taken off your shoulders by introducing Laravel Eloquent.

However, with developers’ complex database and database schemas during the application development process, it’s beneficial to the Laravel community to use Laravel Eloquent to manage and manipulate connected databases efficiently and effectively.

This article will explore Laravel Eloquent ORM and how it interacts with databases seamlessly.

We will walk through the overview of the Laravel Eloquent and how it works.

Next, we will discuss Eloquent models and the features of Laravel Eloquent.

Lastly, we will learn Eloquent relationships, and Eloquent collections and build a CRUD application with Laravel Eloquent.

If you’re ready to explore Laravel Eloquent in detail, let’s dive in:

What you will learn

  1. What is Laravel Eloquent?
  2. Overview of Laravel Eloquent (How it works)
  3. What is a Laravel model?
    1. Creating Eloquent models
    2. Updating and deleting elements
    3. Related model
    4. Model Events
    5. Model Observers
  4. Features of Eloquent
    1. Convert to arrays/JSON
    2. Attribute casting
    3. Date Mutators
    4. Accessors and Mutators
    5. Soft Deleting
  5. Laravel Eloquent Relationships
  6. What are Eloquent Collections?
  7. Implement a CRUD App with Laravel Eloquent
    1. Setting up Laravel
    2. Configuring & seed Database
    3. Defining Laravel Model
    4. Creating Controllers
  8. Summary

What is Laravel Eloquent?

Eloquent is Laravel’s Object Relational Mapper (ORM) with an elegant, beautiful and efficient way of interacting and managing databases.

The Laravel team created Eloquent to ease the interaction and communication with databases and provides an easy-to-use way to address all database and development-related problems.

Laravel Eloquent provides the freedom to write customizable, well-formatted, efficient, easy-to-read, well-documented, and sustainable codes following industry standards and best practices.

Overview of Laravel Eloquent (How it works)

Laravel Eloquent uses ActiveRecord implementation, which makes working with multiple databases a breeze.

Active Record is an architectural pattern that structures each Eloquent Model in the MVC architecture to correspond to the table in the database. 

In addition, you can easily create relational data in your database and work with Object-Oriented Models seamlessly using Laravel Eloquent.

Also, Laravel Eloquent gives you the freedom to create complex database schemas and database interactions without writing and using complex or lengthy SQL queries since SQL queries are tedious and time-consuming to learn and code in a complex application.

In Laravel Eloquent, you don’t need to write any SQL queries. All you need to do is create your database using any database client, define the schemas and relationship between them using Laravel Migration, and Eloquent will handle the rest.

What is a Laravel Model?

Laravel Model is a single PHP object that represents a database schema in a database.

The model helps you interact and communicate with a specific database schema.

Using the Eloquent model, you can perform many database-related functionalities such as creating, updating, reading, and deleting records.

Let’s explore in detail the functionalities that can be performed using Laravel Eloquent Model:

Creating Eloquent models

Eloquent Model is the base of everything in Laravel; before building out your application, you need to define your models.

Creating a model in Laravel can be done in several ways, but we will always follow the best possible and recommended method in this article.

Using Artisan, Laravel’s command-line interface (CLI), you can do almost anything with Laravel Eloquent models.

Run this command to create your first model:

php artisan make:model Todo

Laravel stores all its models in the app/Models folder, though it can be stored anywhere in the app folder and be auto-loaded into your application using the composer.js file.

Once your Todo model is created, and you can explore the content of the file. You will notice that it extends Laravel’s Model object in Illuminate\Database\Eloquent\Model where all the magic happens.

Everything that Eloquent does behind the scene, how it interacts and communicates with multiple databases, starts from the Model class that your generated model extends.

Updating and deleting elements

The following important feature of the Eloquent Model is updating and deleting models without SQL queries.

Updating

To update the attribute of a model, you have to retrieve it first and then change the attribute of the model and lastly, call the save method of that model.

<?php
$todo = Todo::find(1);
$todo->email = ‘[email protected]';
$todo->save();

Deleting

To delete a model, you have to find the model by ID and call the delete method of the model to delete the model record.

<?php
$todo = Todo::find(1);
$todo->delete();

Like many other ways to delete models in Laravel, this is the preferred method to delete a single model.

Related model

Laravel Models can be related to each other same as database relationships and the different types of relationships.

When two models rely on each other for data, then they are called related models. Let’s show a code sample to understand.

$todo = new Todo(['title' => 'Drink water.', 'is_completed' => 'false', 'user_id' => 1]);
$user = User::find(1);
$todo = $user->todos()->save($todo);

These related methods can be either created, updated, retrieved, or deleted using the associated methods. You can set foreign keys and create many to many relationships with models.

Model Events

The different CRUD activities on the Eloquent model come with their corresponding events. Events such as creating, created, updating, updated, etc. are triggered depending on the actions performed on the model.

You can use these events to mutate eloquent model attributes with them, and it’s handy for running model background tasks. For instance, assuming you don’t want to create a new Todo if it is not valid.

You can simply attach this code to the creating event.

Todo::creating(function($todo)
{
    if ( ! $todo>isValid()) return false;
});

Laravel will always execute this event during the Todo creation process before creating the model only if it is valid.

Model Observers

Model observers let you handle all the model events in a single file. You can implement all the model events that you care about inside the observer file.

Let’s look at how to handle it:

class TodoObserver {
    public function creating($model)
    {
        if ( ! $model>isValid()) return false;
    }
    public function created($model)
    {
        //
	$this->notifyUser($model);
    }
    public function updating($model)
    {
        //
	$this->logUpdateRequest($model);
    }
    public function updated($model)
    {
        //
	$this->logSuccessfulUpdate($model);
    }

}

As you can see, there are many things you can achieve with Model Events using Observers to implement them in a single file.

Features of Eloquent

Let’s examine the features of Laravel Eloquents to understand a few great things we can do with Eloquent ORM.

Convert to Arrays/JSON

In Laravel Eloquent, whether you’re building a RESTful API or a monolith application, you might want to return some JSON or Array formatted data.

Laravel Eloquent have you covered right out of the box.

With the toArray() and toJson() methods, you can cover any model in the different formats:

$todos = Todo::all();
$arrayOfTodos = $todos->toArray();
$jsonOfTodos = $todos->toJson();

Attribute Casting

Another benefit of Laravel eloquent is that you can convert the data type of any model to a different data type or force your model to have a strict data type using Attribute Casting.

Let’s examine this code sample:

protected $casts = [
    'is_user' => 'boolean',
    'options' => 'array',
];

Inside the $casts array, you can specify a column and assign a data type to it. This attribute casting can also help to mutate the model’s attributes.

Date Mutators

The date mutator is very useful in Laravel Eloquent as it solves the hassle of manipulating date and time. Laravel uses Carbon, an international PHP extension for DateTime.  

With this combination, it becomes straightforward to customize dates and times in Laravel Eloquent Model. You can choose to use Carbon instance, UNIX timestamp, or date-time.

To customize which dates are mutated (convert to Carbon instance), look at the following code sample:

protected $dates = [
        'created_at',
        'updated_at',
        'deleted_at'
    ]

Accessors and Mutators

To format the attributes of an Eloquent Model before retrieving or setting them in the model instance,  you can use the Eloquent accessor and mutator property to achieve it.

Accessors are used to fetch or retrieve the data, while mutators change the data values.

To implement accessors, look at the following code samples:

class Todo extends Model {
    public function getTitleAttribute($value)
    {
        return ucfirst($value);
    }
}

Next, to implement mutators, look at the following code sample:

class Todo extends Model {
    public function setTitleAttribute($value)
    {
        $this->attributes[‘title’] =  ucfirst($value);
    }
}

Soft Deleting

Soft deleting in Laravel Eloquent is a great feature that needs to be explored in great detail, which is not the scope of this article.

To summarize, soft deleting is a practice in software engineering where a database record is trashed instead of completely deleting the record from the database.

Laravel Eloquent comes with soft deleting out of the box and you only need to use the SoftDeletes trait created by the Laravel team.

use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model {
    use SoftDeletes;
    protected $dates = ['deleted_at'];
}

Next, you add the $table->softDeletes() method to the schema you want soft deleting in your migration and you’re ready to go:

$table->softDeletes();

Lastly, you can start working with only trashed data like the below:

$todos = Todo::onlyTrashed()->where('user_id', 1)->get();

// To restore
$todo->restore();

// To delete permanently
$todo->forceDelete();

Laravel Eloquent Relationships

Managing and creating Database relationships is challenging and requires expert knowledge to develop a scalable solution, especially for enterprise solutions. 

Laravel Eloquent handles model relationships seamlessly and makes it easy to create, manage and access related models.

An eloquent relationship is a complex and extensive topic that requires its content.

However, we have a dedicated article on Laravel relationships to help your understanding of how Laravel Eloquent handles the hassles involved in creating and managing database relationships.

The eloquent relationship is split into:

  1. One to one
  2. One to many
  3. Many to many
  4. Has One Through
  5. Has_many Through
  6. One to One (polymorphic)
  7. One to Many (polymorphic)
  8. Many to Many (polymorphic)

You can get a complete guide on each relationship in the complete guide to the Eloquent relationship.

What are Eloquent Collections?

Laravel Eloquent also comes with great collection features for manipulating arrays and objects. With collections, it becomes convenient to use objects and arrays.

Below is a list of popular collection methods:

  1. Find: Retrieves a single record with the ID in the database.
  2. Contains: The method is used to check if a particular model includes the instance of another model.
  3. Only: This method returns all the models with a given primary key.
  4. Unique: This method returns all the unique models in a collection.

The eloquent collection is an extensive and complex topic. You can learn more of the essential methods from the official documentation.

Build a CRUD App with Laravel Eloquent

Now we’re going to apply what we’ve learned so far by creating a new Laravel project and implementing Laravel Eloquent.

If you haven’t used Laravel, you can read through what Laravel is and peek at our list of excellent Laravel tutorials to get started.

Setting up Laravel

First, we’re going to create a fresh Laravel instance using the below command. You can look up the official documentation for more.

Open your console and navigate to where you store your PHP projects before running the commands below. Make sure to have Composer installed and configured correctly.

composer create-project laravel/laravel laravel-eloquent-app

// Change directory to current Laravel installation
cd laravel-eloquent-app

// Start Laravel development server.
php artisan serve

Configuring & seed Database

Next, we will set up our database, create a new Todo model, and seed 500 fake data for testing.

Open your database client and create a new database. We’ll do the same with the name laravel_eloquent_app_db and then fill up our .env file with the database credentials:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_eloquent_app_db
DB_USERNAME=//DB USERNAME HERE
DB_PASSWORD=//DB PASSWORD HERE

Next, we’ll run the following command to create the migration and the Todo model simultaneously:

php artisan make:model Todo -mc

Open the newly created migration found database/migrations/xxx-create-todos-xxx.php and paste in the following codes:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTodosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description')->nullable();
	$table->boolean(‘is_completed’)->default(false);
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('todos');
    }
}

You can seed your todos with faker data by learning how to seed your databases in Laravel using Faker.

Defining Laravel Model

Open the newly created Todo.php model file found app/Models folder and paste in the following codes:

<?php

namespace App\Models;

use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Todo extends Model
{
    use HasFactory;

}

The code sample shows that the Todo.php model file extends the Model parent class where all the magic of manipulating and managing database-related operations happens.

Creating Controllers

Open the newly created TodosController.php file found in app/Http/Controllers folder and paste in the following codes:

<?php

namespace App\Http\Controllers;
use App\Models\Todo;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class TodosController extends Controller
{
    //
    public function index(Request $request)
    {
        $todos = Todo::all();
        return view('dashboard')->with(['todos' => $todos]);
    }

    public function byUserId(Request $request)
    {
        $todos = Todo::where('user_id', Auth::user()->id)->get();
        return view('dashboard')->with(['todos' => $todos]);
    }

    public function show(Request $request, $id)
    {
        $todo = Todo::find($id);
        return view('show')->with(['todo' => $todo]);
    }

    public function update(Request $request, $id)
    {
        # Validations before updating
        $todo = Todo::where('user_id', Auth::user()->id)->where('id', $id)->first();

        if ($todo) {
            $todo->title = $request->title;
            $todo->desc = $request->desc;
            $todo->status = $request->status == 'on' ? 1 : 0;
            if ($todo->save()) {
                return view('show', ['todo' => $todo]);
            }
            return; // 422
        }
        return; // 401
    }

    public function store(Request $request)
    {
        # Validations before updating
        $todo = new Todo;
        $todo->title = $request->title;
        $todo->desc = $request->desc;
        $todo->user_id = Auth::user()->id;
        if ($todo->save()) {
            return view('show', ['todo' => $todo]);
        }
        return; // 422
    }

    public function delete(Request $request, $id)
    {

        $todo = Todo::where('user_id', Auth::user()->id)->where('id', $id)->first();
        if ($todo) {
            $todo->delete();
            return view('index');
        }
        return; // 404
    }
}

The controller code snippet above shows how to use models in Laravel. With it, you can access and manipulate the database in any way you see fit.

Summary

This article explored Laravel Eloquent ORM and how it interacts with databases seamlessly. We walked through the overview of the Laravel Eloquent and how it works. 

Next, we discussed Eloquent models and the features of Laravel Eloquent. 

Lastly, we learned Eloquent relationships, and Eloquent collections and built a CRUD application with Laravel Eloquent.

Backend Tips, Every week

Backend Tips, Every week