Introduction to Laravel's ORM (Object-Relational Mapping


Eloquent is Laravel's ORM (Object-Relational Mapping), which allows developers to interact with databases using a clean and expressive syntax. It simplifies common database tasks by abstracting them into an object-oriented model, making it easy to perform CRUD (Create, Read, Update, Delete) operations, relationships, and database queries without writing raw SQL.

Key Concepts of Eloquent


1. Defining Eloquent Models

Eloquent models represent the tables in your database, and each instance of a model corresponds to a single row in the table. To create a model, use the make:model Artisan command:

php artisan make:model Post

By default, Eloquent assumes that the model is associated with a table named the plural form of the model's class name (i.e., Post model is mapped to the posts table).

Example of a Model:

namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { // The table name is 'posts' by default, but you can override it protected $table = 'posts'; }

2. Retrieving Data

Eloquent provides several ways to retrieve data from the database.

Basic Retrieval: all()

This method retrieves all rows from the associated table:

$posts = Post::all();

Finding a Record by Primary Key: find()

You can retrieve a single row by its primary key (usually the id):

$post = Post::find(1);

Using where() Clauses

To add constraints to your queries, use the where() method:

$posts = Post::where('status', 'published')->get();

You can also chain multiple where() conditions:

$posts = Post::where('status', 'published') ->where('author_id', 1) ->get();

Getting a Single Row: first() or findOrFail()

To get a single record, you can use first(), which will return the first match or null if no record is found.

$post = Post::where('title', 'My First Post')->first();

To throw an exception if no result is found, use findOrFail() or firstOrFail():

$post = Post::findOrFail(1);

3. Inserting Data

To insert data into the database, you can use the save() method after creating an instance of your Eloquent model.

Example:

$post = new Post; $post->title = 'My First Post'; $post->content = 'This is the content of my post.'; $post->save();

This will insert a new row into the posts table.

Mass Assignment: create()

You can also use mass assignment to insert data into the table more quickly. Ensure you define which fields are mass-assignable in the model by using the $fillable property:

class Post extends Model { protected $fillable = ['title', 'content']; }

Then, you can create a record like this:

Post::create([ 'title' => 'My First Post', 'content' => 'This is the content of my post.', ]);

4. Updating Data

To update a record, retrieve it first and then modify its attributes before calling save():

$post = Post::find(1); $post->title = 'Updated Title'; $post->save();

Mass Update: update()

To update multiple rows at once, use the update() method with a where() clause:

Post::where('status', 'draft')->update(['status' => 'published']);

5. Deleting Data

You can delete records in several ways using Eloquent.

Deleting a Record: delete()

First, retrieve the record, then call delete() on it:

$post = Post::find(1); $post->delete();

Mass Delete: destroy()

To delete multiple records by their primary keys, use the destroy() method:

Post::destroy([1, 2, 3]); // Deletes posts with IDs 1, 2, and 3

6. Eloquent Relationships

Eloquent supports defining relationships between different models, such as one-to-one, one-to-many, many-to-many, etc. This allows you to query related data easily.

One-to-One Relationship

Define a one-to-one relationship using the hasOne() and belongsTo() methods:

// In the User model public function phone() { return $this->hasOne(Phone::class); } // In the Phone model public function user() { return $this->belongsTo(User::class); }

One-to-Many Relationship

For a one-to-many relationship (e.g., a post having many comments):

// In the Post model public function comments() { return $this->hasMany(Comment::class); }

To retrieve comments for a post:

$post = Post::find(1); $comments = $post->comments; // Eager loading of comments

Many-to-Many Relationship

Many-to-many relationships use a pivot table. For example, if posts can belong to multiple tags and tags can be assigned to multiple posts:

// In the Post model public function tags() { return $this->belongsToMany(Tag::class); }

Eager Loading

You can load related models in a single query using eager loading:

$posts = Post::with('comments')->get();

7. Query Scopes

Eloquent allows you to define query logic as reusable functions called scopes. These scopes can be added to the model to simplify your queries.

Defining a Local Scope

In your model, define a method that starts with scope:

class Post extends Model { public function scopePublished($query) { return $query->where('status', 'published'); } }

To use the scope:

$posts = Post::published()->get();

Global Scopes

You can define global scopes to automatically apply to every query:

class PublishedScope implements Scope { public function apply(Builder $builder, Model $model) { $builder->where('status', 'published'); } }

Then in the model:

protected static function booted() { static::addGlobalScope(new PublishedScope); }

8. Soft Deleting

Soft deleting allows you to "delete" records without removing them from the database permanently. This can be useful for preserving data that might be needed later.

Enabling Soft Deletes

First, add the SoftDeletes trait to your model:

use Illuminate\Database\Eloquent\SoftDeletes; class Post extends Model { use SoftDeletes; }

Next, add a deleted_at column to your table via a migration:

$table->softDeletes();

When a record is soft-deleted, it is not removed from the database, but the deleted_at column is filled with a timestamp. You can retrieve soft-deleted records using the withTrashed() method:

$posts = Post::withTrashed()->get();

To restore soft-deleted records:

$post->restore();

9. Timestamps

By default, Eloquent automatically manages the created_at and updated_at columns for every model. If your table does not have these columns, you can disable them in your model:

public $timestamps = false;

10. Mutators and Accessors

Eloquent provides a way to manipulate data when retrieving or setting model attributes.

Accessors

Use accessors to modify the value of a field when it is retrieved:

public function getTitleAttribute($value) { return strtoupper($value); }

Mutators

Use mutators to modify the value before saving it to the database:

public function setTitleAttribute($value) { $this->attributes['title'] = strtolower($value); }

Summary

Eloquent provides a clean and powerful way to interact with your database, making common database operations easier by abstracting SQL queries into intuitive, object-oriented code. Its support for relationships, soft deletes, scopes, and mutators makes it a versatile ORM for building modern web applications.