Laravel Eloquent ORM: Defining Models, Queries, and Data Operations
This tutorial explains how to configure Laravel's Eloquent ORM, create and customize model classes, manage table names, primary keys, timestamps, perform queries, insert, update, delete records, handle soft deletes, apply global and local scopes, and work with model events and observers, all with practical PHP code examples.
Laravel's Eloquent ORM provides a clean ActiveRecord implementation for interacting with databases. Each table has a corresponding model class that extends Illuminate\Database\Eloquent\Model . Before starting, ensure the database connection is configured in config/database.php .
Defining Models
Generate a model using the Artisan command php artisan make:model User . To also create a migration, add the --migration or -m option.
php artisan make:model User php artisan make:model User --migrationEloquent Model Conventions
By default, Eloquent assumes the table name is the snake‑cased plural of the model class (e.g., Flight maps to flights ). Override this by defining a protected $table = 'my_flights'; property.
class Flight extends Model {
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'my_flights';
}The primary key defaults to id . Change it with a protected $primaryKey property, and adjust its type or incrementing behavior as needed.
class Flight extends Model {
protected $primaryKey = 'flight_id';
public $incrementing = false;
protected $keyType = 'string';
}Timestamps
Eloquent automatically maintains created_at and updated_at . Disable them by setting public $timestamps = false; or customize the format with protected $dateFormat = 'U'; . Custom column names can be defined via const CREATED_AT = 'creation_date'; and const UPDATED_AT = 'last_update'; .
class Flight extends Model {
public $timestamps = false;
protected $dateFormat = 'U';
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';
}Retrieving Models
Use static methods like all() , where() , get() , find() , and first() to fetch records. Chain query constraints and retrieve collections via Illuminate\Database\Eloquent\Collection .
$flights = App\Flight::all();
$flight = App\Flight::find(1);
$flight = App\Flight::where('active', 1)->first();Adding Constraints
Apply additional query constraints before calling get() :
$flights = App\Flight::where('active', 1)
->orderBy('name', 'desc')
->take(10)
->get();Collections
Collections provide methods like reject() , each() , and support array‑style iteration.
$flights = $flights->reject(function ($flight) {
return $flight->cancelled;
});
foreach ($flights as $flight) {
echo $flight->name;
}Chunking Results
Process large data sets efficiently with chunk() or cursor() to reduce memory usage.
Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
// process each flight
}
});
foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
// iterate with a cursor
}Inserting & Updating Models
Insert
Create a model instance, set attributes, and call save() :
use App\Flight;
$flight = new Flight;
$flight->name = $request->name;
$flight->save();Update
Retrieve the model, modify attributes, and call save() again. Timestamps are updated automatically.
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save();Bulk Update
Update multiple rows without retrieving models:
App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);Mass Assignment
Define $fillable or $guarded on the model to allow create() or fill() with an attribute array.
class Flight extends Model {
protected $fillable = ['name'];
}
$flight = Flight::create(['name' => 'Flight 10']);
$flight->fill(['name' => 'Flight 22']);Guarded Attributes
Use $guarded as a blacklist, or an empty array to allow all attributes.
protected $guarded = ['price'];
protected $guarded = [];Other Creation Methods
firstOrCreate and firstOrNew attempt to find a record and create one if it does not exist. updateOrCreate updates an existing record or creates a new one.
$flight = Flight::firstOrCreate(['name' => 'Flight 10']);
$flight = Flight::firstOrNew(['name' => 'Flight 10']);
$flight->save();
$flight = Flight::updateOrCreate(['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99]);Deleting Models
Call delete() on an instance, or use destroy() with primary keys to delete without retrieval.
$flight = App\Flight::find(1);
$flight->delete();
App\Flight::destroy(1);
App\Flight::destroy([1, 2, 3]);Bulk Delete
Delete rows matching a condition; model events are not fired.
$deletedRows = App\Flight::where('active', 0)->delete();Soft Deletes
Use the SoftDeletes trait and a deleted_at column to hide records instead of removing them permanently.
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model {
use SoftDeletes;
protected $dates = ['deleted_at'];
}Query helpers: withTrashed() , onlyTrashed() , and restore() . Permanently delete with forceDelete() .
$flights = Flight::withTrashed()->where('account_id', 1)->get();
$flight->restore();
Flight::withTrashed()->where('airline_id', 1)->restore();
$flight->forceDelete();Query Scopes
Global Scopes
Implement Illuminate\Database\Eloquent\Scope and add it in the model's boot() method with addGlobalScope() . Use withoutGlobalScope() or withoutGlobalScopes() to remove them.
class AgeScope implements Scope {
public function apply(Builder $builder, Model $model) {
$builder->where('age', '>', 200);
}
}
class User extends Model {
protected static function boot() {
parent::boot();
static::addGlobalScope(new AgeScope);
}
}
User::withoutGlobalScope(AgeScope::class)->get();
User::withoutGlobalScope('age')->get();
User::withoutGlobalScopes()->get();Local Scopes
Define reusable query fragments with methods prefixed by scope . They can be chained and accept parameters.
class User extends Model {
public function scopePopular($query) {
return $query->where('votes', '>', 100);
}
public function scopeActive($query) {
return $query->where('active', 1);
}
public function scopeOfType($query, $type) {
return $query->where('type', $type);
}
}
$users = User::popular()->active()->orderBy('created_at')->get();
$admins = User::ofType('admin')->get();Events
Eloquent fires events such as retrieved , creating , created , updating , updated , saving , saved , deleting , deleted , restoring , and restored . Map them to custom event classes via the model's $dispatchesEvents property.
class User extends Authenticatable {
protected $dispatchesEvents = [
'saved' => UserSaved::class,
'deleted' => UserDeleted::class,
];
}Observers
Group multiple event listeners in an observer class with methods named after the events. Register the observer in a service provider's boot() method using Model::observe(Observer::class) .
class UserObserver {
public function created(User $user) {
// handle created event
}
public function deleting(User $user) {
// handle deleting event
}
}
// In AppServiceProvider
User::observe(UserObserver::class);Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.