Introduction to Eloquent ORM
In this article, we'll introduce Eloquent's core concepts — models, basic queries, and simple CRUD operations — giving you the foundation needed before we explore more advanced Eloquent features in later articles.
Introduction
With your database configured, migrations defining your table structures, and seeders populating them with realistic data, there's one piece left: actually interacting with that data from within your application. You could write raw SQL queries for every operation, but Laravel offers something far more elegant — Eloquent, its built-in ORM (Object-Relational Mapper).
Eloquent lets you work with your database using expressive, readable PHP syntax instead of raw SQL strings. Each database table is represented by a corresponding "model" class, and each row in that table becomes an instance of that model, with its columns accessible as simple object properties.
In this article, we'll introduce Eloquent's core concepts — models, basic queries, and simple CRUD operations — giving you the foundation needed before we explore more advanced Eloquent features in later articles.
What is an Eloquent Model?
A model is a PHP class that represents a single database table. By convention, Laravel assumes a model named Post corresponds to a table named posts (pluralized, lowercase), though this can be customized if needed.
Creating a Model
php
php artisan make:model PostThis generates a file at app/Models/Post.php:
php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
}That's it — this simple class is now fully capable of querying, creating, updating, and deleting rows in the posts table, without writing a single line of SQL.
Creating a Model with a Migration at the Same Time
As mentioned in our earlier article on Artisan commands, you can generate both a model and its migration together:
php
php artisan make:model Post -mRetrieving Data with Eloquent
Getting All Records
php
$posts = Post::all();This returns every row in the posts table as a collection of Post model instances.
Finding a Single Record by ID
php
$post = Post::find(1);If no record with that ID exists, find() returns null. If you'd rather automatically throw a 404-friendly exception when nothing is found (as we saw in the route model binding article), use:
php
$post = Post::findOrFail(1);Filtering Results with where()
php
$posts = Post::where('is_published', true)->get();You can chain multiple conditions together:
php
$posts = Post::where('is_published', true)
->where('views', '>', 100)
->get();Getting the First Matching Record
php
$post = Post::where('title', 'My First Post')->first();Ordering and Limiting Results
php
$posts = Post::orderBy('created_at', 'desc')->take(5)->get();Creating Records
Using create()
php
Post::create([
'title' => 'My New Post',
'body' => 'This is the content of the post.',
]);For create() to work, the model must define which fields are "mass assignable" using the $fillable property, as a security measure against unintended data being saved:
php
class Post extends Model
{
protected $fillable = ['title', 'body'];
}Creating a Record Manually
Alternatively, you can build and save a model instance manually:
php
$post = new Post();
$post->title = 'My New Post';
$post->body = 'This is the content of the post.';
$post->save();Updating Records
php
$post = Post::find(1);
$post->title = 'Updated Title';
$post->save();Or, more concisely, using update() directly:
php
Post::find(1)->update(['title' => 'Updated Title']);Deleting Records
php
$post = Post::find(1);
$post->delete();Or in a single line:
php
Post::destroy(1);destroy() also accepts multiple IDs at once:
php
Post::destroy([1, 2, 3]);Accessing Model Data
Once you have a model instance, its columns are accessible as simple object properties:
php
$post = Post::find(1);
echo $post->title;
echo $post->body;
echo $post->created_at;This works because Eloquent automatically maps database columns to properties on the model instance, without you needing to define them manually.
Tips for Getting Started with Eloquent
Always define
$fillableon your models before usingcreate()or massupdate(), or Laravel will throw aMassAssignmentExceptionas a protective default.Use
findOrFail()in controllers instead offind(), so missing records automatically result in a clean 404 response rather than a null-related error further down the line.Chain query methods for readability, like
Post::where(...)->orderBy(...)->get(), rather than building overly complex single queries.Use Tinker to experiment with Eloquent queries before writing them into your actual application code — it's a fast way to test syntax and see real results.
Remember model names are singular, table names are plural by Laravel convention (
Postmodel,poststable), which keeps things predictable across your application.
FAQ About Eloquent
1. Do I need to manually define every column as a property on my model? No. Eloquent automatically detects columns from the underlying database table at runtime, so you don't need to declare them individually in the model class.
2. What's the difference between find() and where()->first()? find() is a shortcut specifically for looking up a record by its primary key, while where()->first() is more general-purpose, letting you search by any column and condition.
3. Why did I get a MassAssignmentException when using create()? This happens when the model doesn't have a $fillable (or $guarded) property defined, which Laravel requires as a safeguard against unintended fields being saved from user input.
4. What's the difference between $fillable and $guarded? $fillable is a whitelist — only the listed fields can be mass assigned. $guarded is the opposite, a blacklist — all fields except the listed ones can be mass assigned. Most developers prefer $fillable for clearer, more explicit control.
5. Does Eloquent work with databases other than MySQL? Yes, Eloquent works the same way regardless of which supported database driver you're using (MySQL, PostgreSQL, SQLite, SQL Server), since it abstracts away most database-specific differences.
6. Is Eloquent slower than writing raw SQL queries? There's a small overhead compared to raw SQL, but for the vast majority of applications, this difference is negligible compared to the significant gains in code readability, maintainability, and development speed.
Conclusion
Eloquent transforms database interaction from writing raw SQL strings into simple, expressive PHP that reads almost like plain English. With models representing your tables and a clean, chainable query syntax, you can handle the vast majority of your application's data needs without ever touching SQL directly.
In the next article, we'll compare Eloquent to Laravel's Query Builder — another way to interact with your database — and explain when each approach makes more sense.
Found this helpful? Share it!