Laravel tips: DB Models and Eloquent - Part 2

Websolutionstuff | Oct-13-2023 | Categories : Laravel MySQL

Laravel, the PHP web application framework, is renowned for its elegant and efficient approach to handling databases through its ORM (Object-Relational Mapping) called Eloquent.

Whether you're a seasoned Laravel developer or just starting your journey, mastering Eloquent and its accompanying database models can significantly streamline your development process.

In this article, we'll dive straight into the heart of Laravel's Eloquent ORM and explore a series of quick tips that can make your database interactions smoother, your code more concise, and your applications more powerful.

These tips are designed to be practical, actionable, and immediately beneficial to your Laravel projects.

From optimizing queries to leveraging relationships and handling common scenarios, we'll cover a range of essential Eloquent techniques. Each tip comes with code examples to illustrate its implementation and show how it can enhance your Laravel applications.

Let's see Laravel Tips, Laravel Tricks, top 10 Tricks and Tips Laravel, 10 laravel eloquent Tips and Tricks, Laravel Tips and Tricks 2023, and laravel advanced tips.

1. New `rawValue()` method

Laravel 9.37 has a new rawValue() method to get a value from an SQL expression.

$first = PostModel::orderBy('date_at', 'ASC')
     ->rawValue('YEAR(`date_at`)');

$last = PostModel::orderBy('date_at', 'DESC')
     ->rawValue('YEAR(`date_at`)');
 
$fullname = UserModel::where('id', $id)
     ->rawValue('CONCAT(`first_name`, " ", `last_name`)');

 

2. Eloquent scopes inside of other relationships

You can use Eloquent scopes inside of defining other relationships.

app/Models/Lesson.php

public function scopePublished($query)
{
     return $query->where('is_published', true);
}

app/Models/Course.php

public function lessons(): HasMany
{
     return $this->hasMany(Lesson::class);
}
 
public function publishedLessons(): HasMany
{
     return $this->lessons()->published();
}

 

3. Transaction-aware code

Using DB::afterCommit method you can write code that will only be executed if the transaction gets committed and discarded if the transaction is rolled back.

If there is no transaction, the code will be executed right away

DB::beginTransaction(); // Start a transaction
// Perform database operations
DB::commit(); // Commit the transaction
// OR
DB::rollback(); // Rollback the transaction

Example:

DB::transaction(function () {
     $user = User::create([...]);
 
     $user->teams()->create([...]);
});

The afterCommit method in Laravel is a feature that allows you to define actions that should be executed after a database transaction is successfully committed. This can be particularly useful when you want to perform certain tasks only when changes to the database have been permanently saved, ensuring data consistency.

class User extends Model
{
     protected static function booted()
     {
          static::created(function ($user) {
               // Will send the email only if the
               // transaction is committed
               DB::afterCommit(function () use ($user) {
                    Mail::send(new WelcomeEmail($user));
               });
          });
     }
}

 

 

4. Perform operation without modifying updated_at field

In Laravel, the withoutTimestamps method is used to specify that a model should not automatically manage the created_at and updated_at timestamp columns.

By default, Laravel's Eloquent ORM automatically manages these columns, updating created_at when a new record is created and updated_at when a record is updated.

However, in some cases, you may want to exclude these timestamps from certain operations or models.

You can disable timestamps for specific operations using the withoutTimestamps method. This is helpful if you want to override the global timestamp configuration for specific cases.

Available from Laravel 9.31.

Example:

use App\Models\YourModel;

// Disable timestamps for a specific operation
YourModel::withoutTimestamps()->create([...]);

// Perform other operations without timestamps
YourModel::withoutTimestamps()->update([...]);
$user = User::first();
 
// `updated_at` is not changed...
 
User::withoutTimestamps(
     fn () => $user->update(['reserved_at' => now()])
);

 

5. Merging eloquent collections

The Eloquent collection's merge method uses the id to avoid duplicated models. Merging Eloquent collections in Laravel allows you to combine multiple collections into one, which can be useful for tasks like combining query results or aggregating data from different sources.

You can merge collections using various methods provided by Laravel's Eloquent ORM. Here's how you can merge Eloquent collections.

1. Using concat() Method:

The concat() method is a straightforward way to merge two or more Eloquent collections. You can use it like this:

$collection1 = Model::where(...)->get();
$collection2 = Model::where(...)->get();
$mergedCollection = $collection1->concat($collection2);

 

2. Using the merge() Method:

The merge() method is another way to combine Eloquent collections. It works similarly to concat():

$collection1 = Model::where(...)->get();
$collection2 = Model::where(...)->get();
$mergedCollection = $collection1->merge($collection2);

Both concat() and merge() methods return a new collection containing the merged data, leaving the original collections unchanged.

 

3. Using union() Method:

The union() method is useful when you want to merge collections and remove duplicate items. It combines the collections while ensuring that each item is unique:

$collection1 = Model::where(...)->get();
$collection2 = Model::where(...)->get();
$mergedCollection = $collection1->union($collection2);

 

6. Full-Text Search with Laravel on MySQL

Implementing full-text search in Laravel with MySQL can greatly enhance the search capabilities of your application, allowing users to find relevant information more efficiently.

Migration:

Schema::create('comments', function (Blueprint $table) {
     $table->id();
     $table->string('title');
     $table->text('description');
 
     $table->fullText(['title', 'description']);
});

Natural language

Search for something

Comment::whereFulltext(['title', 'description'], 'something')->get();

Natural language with Query Expansion

Search for something and use the results to perform a larger query

Comment::whereFulltext(['title', 'description'], 'something', ['expanded' => true])->get();

 

7. Bindings raw queries

In Laravel, you can use query bindings in raw SQL queries to improve security and maintainability. Query bindings help prevent SQL injection and make your code more readable. Here's how to use query bindings in raw queries in Laravel:

// This is vulnerable to SQL injection
$fullname = request('full_name');
User::whereRaw("CONCAT(first_name, last_name) = $fullName")->get();
 
// Use bindings
User::whereRaw("CONCAT(first_name, last_name) = ?", [request('full_name')])->get();
$query = "SELECT * FROM users WHERE id = :userId";
$results = DB::select(DB::raw($query), ['userId' => 1]);

 

8. Reuse or clone query()

Typically, we need to query multiple time from a filtered query. So, most of the time we use query() method.

In Laravel, the clone method is not directly available for the query() builder instance. However, you can achieve similar functionality by creating a new query builder instance and copying the desired parts of the original query. Here's how you can clone a query() builder instance in Laravel

let's write a query for getting today created active and inactive products.

 
$query = Product::query();
 
 
$today = request()->q_date ?? today();
if($today){
    $query->where('created_at', $today);
}
 
// lets get active and inactive products
$active_products = $query->where('status', 1)->get(); // this line modified the $query object variable
$inactive_products = $query->where('status', 0)->get(); // so here we will not find any inactive products

After getting $active products the $query will be modified. So, $inactive_products will not find any inactive products from $query and that will return blank collection every time. Cause, that will try to find inactive products from $active_products ($query will return active products only).

To solve this issue, we can query multiple times by reusing this $query object. So, We need to clone this $query before doing any $query modification action.

$active_products = $query->clone()->where('status', 1)->get(); // it will not modify the $query
$inactive_products = $query->clone()->where('status', 0)->get(); // so we will get inactive products from $query

 

 

9. Eloquent where date methods

Laravel's Eloquent ORM provides several methods for querying database records based on date and time values. These methods allow you to easily filter records based on various date-related criteria. Here are some common Eloquent where methods related to date and time.

In Eloquent, check the date with functions whereDay()whereMonth()whereYear()whereDate() and whereTime().

$users = User::whereDate('created_at', '=', '2023-01-15')->get();

$users = User::whereMonth('created_at', 2)->get();

$users = User::whereDay('birthdate', 5)->get();

$users = User::whereYear('birthdate', 1990)->get();

$users = User::whereTime('created_at', '=', '14:30:00')->get();

$users = User::whereBetween('birthdate', ['1990-01-01', '1999-12-31'])->get();

$users = User::whereDate('created_at', '2023-01-15')
    ->orWhereDate('updated_at', '2023-01-15')
    ->get();

 

10. Soft-deletes: multiple restore

In Laravel's Eloquent ORM, soft deletes are a way to "softly" delete records by marking them as deleted without actually removing them from the database.

This allows you to retain a record of the deleted item while excluding it from regular queries. You can restore soft-deleted records individually using the restore method or restore multiple records at once using various techniques.

Here's how you can restore multiple soft-deleted records in Laravel:

1. Using the whereIn Method:

You can restore multiple soft-deleted records by specifying a list of primary keys for the records you want to restore. Here's an example:

$idsToRestore = [1, 2, 3];

User::whereIn('id', $idsToRestore)->restore();

 

2. Using the restore Method with a Query:

You can also restore multiple records using a query to filter the soft-deleted records you want to restore. For example:

Post::onlyTrashed()->where('author_id', 1)->restore();

Users::where('deleted_at', '<>', null)->restore();

 


You might also like:

Recommended Post
Featured Post
How To Merge Two Collections In Laravel
How To Merge Two Collections I...

In this article, we will see how to merge two collections in laravel 8 or laravel 9. The Illuminate\Support\Co...

Read More

Jul-18-2022

How to Reset MySQL Root User Password on Ubuntu
How to Reset MySQL Root User P...

Hey there! If you've ever found yourself scratching your head over a forgotten MySQL root password on Ubuntu, fear n...

Read More

Jan-26-2024

How To Image Upload With Preview In Angular 15
How To Image Upload With Previ...

In today's world of web development, being able to upload images with a preview feature is a common requirement for...

Read More

Jun-16-2023

Laravel 9 Socialite Login With Twitter Account
Laravel 9 Socialite Login With...

In this article, we will see laravel 9 socialite login with twitter account. Many websites provide different t...

Read More

Nov-12-2022