Laravel is one of the most popular PHP frameworks in the world, and one of the biggest reasons behind its popularity is Eloquent ORM. Eloquent is Laravel’s built-in Object Relational Mapper that allows developers to work with databases using clean, expressive, and easy-to-understand PHP code instead of writing long and complex SQL queries. Because of Eloquent, developers can interact with database tables like they are working with simple PHP objects.
This 3000-word guide will explain Eloquent ORM from the ground up. You will learn what ORM means, how Eloquent works internally, how models represent database tables, how rows behave like objects, and why Eloquent is more powerful and safer than raw SQL. This guide also covers key Eloquent features such as querying, inserting, updating, deleting, relationships, scopes, casting, timestamps, and more.
By the end of this article, you will have a strong understanding of Eloquent ORM and how it simplifies Laravel application development.
Understanding the Concept of ORM
ORM stands for Object Relational Mapping. It is a programming technique used to convert data between incompatible types, particularly between relational databases and object-oriented programming languages. Without ORM, developers must manually write SQL queries to interact with the database. With ORM, those interactions become object-oriented operations.
For example, without ORM, you might write:
SELECT * FROM users WHERE id = 1;
With ORM, you write:
User::find(1);
Instead of writing SQL statements, you call PHP methods. Instead of SQL rows, you get PHP objects. Instead of manually constructing queries, you write simple readable code that ORM converts into optimized SQL.
Laravel uses Eloquent as its default ORM, providing a smooth and expressive method of communicating with the database.
How Eloquent ORM Works in Laravel
Eloquent follows a convention-based design. This means that if you follow Laravel’s naming rules, everything works automatically. For example, each database table corresponds to a model, and each model represents a table.
If you create a model called Product, Eloquent assumes the table name is products.
When you create a model using Artisan:
php artisan make:model Product
Laravel creates:
app/Models/Product.php
Inside the model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
//
}
This model now represents the products table. Eloquent automatically knows:
- The table name is products
- The primary key is id
- The timestamps are created_at and updated_at
- Each row will be a Product object
This automatic mapping is why Eloquent is called expressive.
Models Represent Database Tables
A Model in Laravel is a PHP class that represents a database table. For example, a User model represents the users table. A Product model represents the products table.
Each model extends the base Model class:
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
}
Every instance of this model represents a single row in the database. For example:
$product = Product::find(1);
Here, $product is not an array or a SQL result. It is an object of the Product model. You can access its properties like this:
$product->name;
$product->price;
This makes working with database records extremely simple.
Each Record Becomes an Object
Eloquent converts each database row into an object of the model. That means you can use object syntax to access record fields.
$user = User::find(1);
echo $user->email;
You do not need to loop through SQL results, fetch arrays, or map values. Every column becomes an object property automatically.
You can also update values directly:
$user->name = "Michael";
$user->save();
Eloquent automatically generates the SQL needed to update the record. This abstraction removes repetitive low-level work.
Writing Queries With Eloquent ORM
One of the most powerful benefits of Eloquent is its expressive query syntax. Instead of writing raw SQL, you write readable PHP.
A simple SQL query like:
SELECT * FROM products;
Becomes:
Product::all();
A conditional SQL query like:
SELECT * FROM products WHERE price > 100;
Becomes:
Product::where('price', '>', 100)->get();
A query to fetch a single row:
SELECT * FROM users WHERE id = 1 LIMIT 1;
Becomes:
User::find(1);
More complex queries like ordering, grouping, and limiting are also very simple:
Product::orderBy('name')->limit(10)->get();
This fluent syntax allows developers to write readable and reusable queries.
Inserting Data With Eloquent
To insert a new record using SQL, you would write:
INSERT INTO products (name, price) VALUES ('Phone', 200);
With Eloquent, you write:
Product::create([
'name' => 'Phone',
'price' => 200
]);
Alternatively:
$product = new Product;
$product->name = 'Phone';
$product->price = 200;
$product->save();
For this to work, you must define fillable fields:
protected $fillable = ['name', 'price'];
Eloquent protects against mass-assignment vulnerabilities, making your application secure by default.
Updating Records With Eloquent
Updating SQL:
UPDATE products SET price = 300 WHERE id = 1;
Updating with Eloquent:
$product = Product::find(1);
$product->price = 300;
$product->save();
Or update multiple rows:
Product::where('category', 'electronics')->update(['discount' => 10]);
Laravel automatically updates the updated_at timestamp unless you disable it.
Deleting Records With Eloquent
SQL:
DELETE FROM products WHERE id = 1;
Eloquent:
Product::destroy(1);
Or:
$product = Product::find(1);
$product->delete();
Soft deletes are also supported, meaning deleted records go into a “trashed” state instead of being removed.
Eloquent Relationships Overview
Eloquent allows you to define relationships between tables using simple methods inside models. These relationships represent how tables connect.
Available relationships:
- One to One
- One to Many
- Many to Many
- Has One Through
- Has Many Through
- Polymorphic One to One
- Polymorphic One to Many
- Many to Many Polymorphic
Example: A user has many posts.
In User model:
public function posts()
{
return $this->hasMany(Post::class);
}
In Post model:
public function user()
{
return $this->belongsTo(User::class);
}
Fetching posts of a user:
$user->posts;
Fetching a post’s user:
$post->user;
Eloquent handles all SQL joins internally.
Querying Relationships
Get all posts for a user:
$posts = User::find(1)->posts;
Lazy loading:
$user->posts;
Eager loading:
User::with('posts')->get();
Eager loading prevents repeated queries and increases performance.
Attribute Casting in Eloquent
Eloquent allows automatic conversion of data types.
Example:
protected $casts = [
'created_at' => 'datetime',
'is_admin' => 'boolean'
];
Now these attributes behave as native PHP types.
Using Accessors and Mutators
Accessors format values when retrieving them.
Mutators format values before saving them.
Accessor:
public function getNameAttribute($value)
{
return ucfirst($value);
}
Mutator:
public function setNameAttribute($value)
{
$this->attributes['name'] = strtolower($value);
}
These help maintain consistent and formatted data.
Query Scopes in Eloquent
Query scopes allow reusing common query patterns.
Local scope:
public function scopeActive($query)
{
return $query->where('status', 'active');
}
Use:
User::active()->get();
Global scopes can apply filters across all queries.
Mass Assignment Protection
Eloquent protects your application from mass assignment vulnerabilities.
Two options:
protected $fillable = [];
or
protected $guarded = [];
Fillable allows only specific fields.
Guarded blocks specific fields.
Timestamps in Eloquent
Eloquent automatically manages fields:
- created_at
- updated_at
You can disable timestamps:
public $timestamps = false;
Or customize column names:
const CREATED_AT = 'created';
const UPDATED_AT = 'modified';
Primary Keys and Table Names
Eloquent assumes:
- primary key is id
- table name is plural of model name
To override the table name:
protected $table = 'my_table';
To override primary key:
protected $primaryKey = 'product_id';
Working With Collections in Eloquent
Eloquent returns data as a collection.
Collections allow:
- filtering
- mapping
- reducing
- sorting
- grouping
Example:
$products->where('price', '>', 100);
Collections are extremely powerful when handling multiple records.
Using Raw Expressions With Eloquent
Sometimes raw SQL is needed.
Product::whereRaw('price > 100')->get();
Or:
DB::raw('COUNT(*) as total');
Eloquent allows combining raw statements with expressive queries.
Pagination With Eloquent
Eloquent supports pagination out of the box.
Product::paginate(10);
Simple pagination:
Product::simplePaginate(5);
Display in Blade:
{{ $products->links() }}
Pagination automatically generates navigation links.
Eloquent and JSON Responses
Eloquent models can be converted to JSON instantly.
return Product::all();
Or manually:
return response()->json($product);
Laravel converts model attributes into JSON fields.
The Benefits of Using Eloquent ORM
Eloquent makes database operations:
- simpler
- faster
- more readable
- scalable
- secure
- expressive
- intuitive
Developers write less code and achieve more.
Key Eloquent advantages:
- Eliminates repetitive SQL queries
- Reduces complexity
- Enhances readability
- Supports relationships naturally
- Provides built-in security features
- Offers powerful query building
- Includes helpful mapping and casting
- Makes large applications maintainable
Because of these benefits, Eloquent is one of the strongest parts of Laravel.
A Complete Example Using Eloquent
Model:
class Product extends Model
{
protected $fillable = ['name', 'price'];
}
Controller:
public function index()
{
$products = Product::where('price', '>', 50)->get();
return view('products.index', compact('products'));
}
View:
@foreach($products as $product)
<p>{{ $product->name }} - {{ $product->price }}</p>
@endforeach
This example shows how models, controllers, and views interact using Eloquent.
Leave a Reply