Innovate | Connect | Transform
ContactService statusUSD $

GICT knowledge base

Leveraging Laravel Eloquent ORM for Database Interactions

Published

You may know very well that Laravel is a robust PHP web application framework that simplifies the process of building web applications. This framework covers everything from handling routes and templates to managing database migrations and authentication.

One of the key aspects is dealing with databases efficiently. And that’s why Laravel comes with a built-in Eloquent Object-Relational Mapping (ORM) system.

In simple terms, it’s a translator between your code and the database, making it easy for developers to understand and smooth the entire process of working with databases.

In this article, we’ll look at how Eloquent simplifies how we interact with Laravel databases. So, let’s start by understanding what Eloquent ORM is.

 

What is Eloquent ORM?

Eloquent ORM or we can say Object-Relational Mapping, is Laravel’s way of making communication with databases more like a conversation than a technical task. Instead of writing SQL queries, you can efficiently use Laravel Eloquent to speak with databases in a developer-friendly way.

This approach not only simplifies the process but also makes your code cleaner and more understandable. It bridges the php code you write and the database where your application stores information.

The main advantage of using Eloquent is –

  • it simplifies the process of readability and maintainability.
  • Writing Eloquent code is often faster than crafting raw SQL queries.

 

Setting Up Laravel and Eloquent

Install Laravel

Before creating a Laravel project, ensure you have PHP and Composer installed.

To create a laravel project, open the terminal and run the below command.

composer create-project laravel/laravel Eloquent-test

Configure Database Connection

Once you create a project, locate the .env file, and you’ll find settings for your database connection. Fill in details like database name, username, and password. For example:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=EloquentDB
DB_USERNAME=darshan
DB_PASSWORD=qswaefrd

Artisan Commands for Eloquent

You can use the Laravel artisan command line tool to create an eloquent model. It acts as a PHP representation of a database table.

Open the terminal and run the following command.

php artisan make:model UserProfile --migration

Your model is like a blueprint for interacting with a specific table in the database. It’s where you define relationships. And –migration or -m is used to create a migration file and a model.

Define Table in Migration

A migration file has two methods: up and down. In the ‘up’ method, define the structure of the table.

// In the create_profiles_table migration file
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained(); // Foreign key to associate with the User model
$table->string('first_name');
$table->string('last_name');
$table->date('birthdate');
$table->string('location');
// Add more fields as needed
$table->timestamps();
});
}

Run the migration command after defining the table.

php artisan migrate

Defining Models:

It’s time to let Eloquent know how to interact with it through your model. So open the UserProfile model you created and define it as follows:

// app/Models/UserProfile.php

namespace App\Models;

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

class UserProfile extends Model
{
use HasFactory;

protected $fillable = [
'id',
'user_id',
'first_name',
'last_name',
'birthdate',
'location',
// Add more fields as needed
];

// Define the relationship with the User model
public function user()
{
return $this->belongsTo(User::class);
}
}

 

CRUD Operations with Eloquent:

Create a record with Eloquent

Now open the controller or wherever you handle the logic. First, we use the create method of eloquent to add the record to the database.

$newRecord = UserProfile::create([
'user_id' => 1,
'first_name' => 'Darshan',
'last_name' => 'Siroya',
'birthdate' => '2000-12-12',
'location' => 'Dubai'

// Add other columns and values as needed
]);

This will create a new record in the database table.

Reading data with an Eloquent is just as easy. Here are some example:

First we retrieve all records.

$allRecords = UserProfile::all();

You can find record by its primary key as following:

$record = UserProfile::find(1); // Replace 1 with the actual primary key

Query records based on conditions:

$filteredRecords = UserProfile::where('name', 'like', 'Darshan')->get();

 

Update and Delete records with Eloquent

To update records, you can use the update method. Here’s an example:

$updatedRecord = UserProfile::where('id', 1)->update([
'first_name' => 'Smit',
// Add other columns and values as needed
]);

Alternatively, you can retrieve the record, modify its attribute, and then save it:

$record = UserProfile::find(1);
$record->first_name = 'Smit';
$record->save();

Deleting records is straightforward with Eloquent. You can use the destroy method to delete a record by its primary key.

UserProfile::destroy(1); // Deletes the record with id 1

To delete the record based on certain conditions, you can use the where method:

UserProfile::where('first_name', 'like', 'Smit')->delete();

 

Eloquent Relationships

Using Eloquent is worthwhile when you define relationships between different models. Let’s explore a few common types.

 

One-to-One Relationship

If each record in one table corresponds to exactly one record in another table, you have a one-to-one relationship. For example, a user might have one profile.

// In app/Models/UserProfile.php

namespace App\Models;

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

class UserProfile extends Model
{

//existing code here …

public function user()
{
return $this->belongsTo(User::class);
}
}

 

One-to-Many Relationship

If one record in a table can be associated with many records in another table, you have a one-to-many relationship. For example, a user can have multiple posts(assuming the Post model is already created).

// In app/Models/User.php
namespace App\Models;

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

class User extends Model
{

//existing code here ...

public function posts()
{
return $this->hasMany(Post::class);
}
}

Many-to-Many Relationship

If records in both tables can have many associated records in the other table, you have a many-to-many relationship. For example, users can have multiple roles belonging to various users(here, we assume that the Role model is already created).

// In app/Models/UserProfile.php
namespace App\Models;

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

class UserProfile extends Model
{

//existing code here ...

public function roles()
{
return $this->belongsToMany(Role::class);
}
}

And in the Role model, you can define the following.

// In app/Models/Role.php
namespace App\Models;

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

class Role extends Model
{

//existing code here ...

public function userProfiles()
{
return $this->belongsToMany(UserProfil::class);
}
}

 

Advanced Eloquent Features

Eloquent’s advanced features make Eloquent even more powerful and flexible. Let’s use it with examples.

Scopes

You can use the Scope feature to summarize your query logic into a function within a model. It helps organize and reuse query constraints in your Eloquent models, making your code more readable.

Scopes are defined as public methods in your Eloquent model. By convention, scope methods are prefixed with scope in the method name. Let’s take an example where you want to retrieve all users with a given role:

// In app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
public function scopeByRole($query, $role)
{
return $query->where('role', $role);
}
}

The above example defines a scope called ByRole, which takes a query builder instance and role parameters.

You can use the scope like the one below.

$users = User::byRole('admin')->get();

The above example defines a scope called ByRole, which takes a query builder instance and role parameters.

You can use the scope like the one below.

$users = User::byRole('admin')->get();

In this example, we’re retrieving all users with the role ‘admin.’

Dynamic Scopes

You can also create dynamic scopes that accept parameters. Let’s create a dynamic scope to retrieve users created after a certain date:

// In app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
public function scopeCreatedAfter($query, $date)
{
return $query->where('created_at', '>', $date);
}
}

Now, you can use the above-created scope dynamically.

$users = User::createdAfter('2023-01-01')->get();

Chaining Scopes

The powerful feature of Eloquent scopes is the ability to chain them together. The example below retrieves all the admin users created after a specific date.

$users = User::byRole('admin')->createdAfter('2023-01-01')->get();

In this way, you can make queries in less time in a more understandable way. Isn’t it?

Global Scope

Global scopes allow you to apply conditions to all queries for a given model. For example, if you always want to retrieve “published” records:

// In YourModelName.php
protected static function boot()
{
parent::boot();

static::addGlobalScope('published', function (Builder $builder) {
$builder->where('published', 1);
});
}

to retrieve all records with the global scope applied:

$publishedRecords = YourModelName::all();

If you want to remove a global scope temporarily, you can use the withoutGlobalScope method:

$recordsWithoutPublishedScope = YourModelName::withoutGlobalScope('published')->get();

 

Accessors

You can use accessors to format or modify the data before it is presented to the user or used in your application.

Let’s get it with an example. Imagine a scenario where you manage a blog featuring user profiles, and each user has a “full name” that combines their first and last names. Your database stores the first and last names separately, but you want to display the full name easily. Accessors help you with that.

// In app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
// ...

// Accessor for the 'full_name' attribute
public function getFullNameAttribute()
{
return ucfirst($this->attributes['first_name']) . ' ' . ucfirst($this->attributes['last_name']);
}
}

In this example, the getFullNameAttribute method will be automatically called when you try to access the full_name attribute on a User model instance.

You can use accessors just like any other attribute on your model.

$user = User::find(1);

// Accessing the 'full_name' attribute, which triggers the accessor
echo $user->full_name;

Accessor Parameters:

You can also use parameters with accessors. For example, you might want to format a date attribute in a specific way:

// In app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
// ...

// Accessor for the 'formatted_birthdate' attribute
public function getFormattedBirthdateAttribute($format = 'Y-m-d')
{
return $this->attributes['birthdate']->format($format);
}
}

You can use accessors with or without providing a format for fetching data.

$user = User::find(1);

// Accessing the 'formatted_birthdate' attribute with the default format
echo $user->formatted_birthdate; // Outputs: 1990-01-01

// Accessing the 'formatted_birthdate' attribute with a custom format
echo $user->formatted_birthdate('F j, Y'); // Outputs: January 1, 1990

Note that accessors are not stored in the database; they are only used when retrieving data from the database.

Mutators

You can use the mutators feature by defining a method on your Eloquent model with a specific naming convention.

The method name should be in the format set{AttributeName}Attribute, where {AttributeName} is the camel-cased name of the attribute you want to mutate. Here’s an example:

// In app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
// ...

// Mutator for the 'email' attribute
public function setEmailAttribute($value)
{
$this->attributes['email'] = strtolower($value);
}
}

The setEmailAttribute method will be automatically called when you try to set the ’email’ attribute on a User model instance.

After setting the value on the model, you can use mutators like the following.

$user = new User;
$user->email = "[email protected]";
echo $user->email; // Outputs: [email protected]

Mutator Parameters

You can also use parameters with mutators. For example, you can use mutators like the following to format a date in a specific way.

// In app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
// ...

// Mutator for the 'birthdate' attribute
public function setBirthdateAttribute($value, $format = 'Y-m-d')
{
$this->attributes['birthdate'] = \Carbon\Carbon::createFromFormat($format, $value);
}
}

Now you can use the mutator with or without providing parameters.

$user = new User;
$user->birthdate = '1990-01-01';
echo $user->birthdate; // Outputs: 1990-01-01

$user->birthdate = 'January 1, 1990';
echo $user->birthdate; // Outputs: 1990-01-01

 

Optimizing Your Application with Eloquent: Performance Tips

  • Eager loading: This technique loads specified relationships along with the primary model to avoid the “N+1 query problem”. Here are simple examples of without and with using eager loading.

 

// Without Eager Loading
$author = Author::find(1);
$books = $author->books; // This may cause additional queries.

// With Eager Loading
$author = Author::with('books')->find(1); // This loads the books along with the author in one go.

  • Indexing: Make sure that your database model is perfectly indexed, especially columns that are involved in search, filtering, or joining operations. It can help speed up your query performance.
  • Chunking Results: When working with large datasets, consider using the chunk method instead of get to process results in smaller chunks. This prevents memory issues when dealing with a substantial amount of data.

 

YourModelName::chunk(200, function ($records) {
// Process each chunk of 200 records
});

  • Database Transactions: When you perform multiple database operations, use them in a database transaction. This can improve your query performance by reducing the number of commits.

 

DB::transaction(function () {
// Your Eloquent operations here
});

That’s it. We’ve discovered how Eloquent ORM simplifies how we talk to databases, making our code cleaner and more readable.

You can check more information about Laravel Eloquent in Laravel’s official documentation.

 

Account services are unavailable until the production backend is configured.