ELOQUENT ORM

Last updated: June 29th 2026

ELOQUENT ORM

The framework ships with Eloquent ORM (v10) as its database layer. Every model extends Eloquent, giving you access to the full Eloquent feature set — relationships, query builder, accessors, mutators, scopes, pagination, soft deletes, and more.

Get Started

Database Connection

Your database config is in app/Config/Database.php:

define('DBENGINE', 'mysql');
define('DBSERVER', 'localhost');
define('DBNAME',   'your_database');
define('DBUSER',   'root');
define('DBPASS',   '');

The connection is established automatically by the framework's ControllerDispatcher on every request that reaches a controller. It uses Eloquent's Capsule\Manager internally and supports: mysql, pgsql, sqlite, sqlsrv.

Models

Create a model using the CLI:

$ php cli make:model User

This generates app/Models/User.php which extends Simple\Model (which extends Eloquent):

namespace App\Models;

use Simple\Model;

class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['name', 'email', 'password'];
}

Eloquent assumes your table name is the plural snake_case of your class name (Userusers), so the $table property is optional if you follow that convention.

Basic CRUD

Create

$user = new User;
$user->name = 'John';
$user->email = '[email protected]';
$user->save();

// Or use create() (requires $fillable):
User::create([
    'name' => 'John',
    'email' => '[email protected]',
]);

Read

$user = User::find(1);
$user = User::where('email', '[email protected]')->first();

$users = User::where('active', true)->get();
$users = User::all();

$count = User::where('active', true)->count();

Update

$user = User::find(1);
$user->name = 'Jane';
$user->save();

// Or mass update:
User::where('active', false)->update(['active' => true]);

Delete

$user = User::find(1);
$user->delete();

// Delete without loading the model:
User::destroy(1);

// Mass delete:
User::where('active', false)->delete();

Query Builder

Eloquent includes a fluent query builder for more complex queries:

$users = User::select('id', 'name', 'email')
    ->where('active', true)
    ->where('role', '!=', 'admin')
    ->orWhere('points', '>', 100)
    ->orderBy('name', 'asc')
    ->limit(10)
    ->get();

// Joins
$users = DB::table('users')
    ->join('contacts', 'users.id', '=', 'contacts.user_id')
    ->select('users.*', 'contacts.phone')
    ->get();

// Aggregates
$max = User::where('active', true)->max('points');
$avg = User::avg('rating');

// Subqueries
$posts = Post::whereIn('user_id', function ($q) {
    $q->select('id')->from('users')->where('active', true);
})->get();

Relationships

Eloquent supports all common relationship types:

class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    public function profile()
    {
        return $this->hasOne(Profile::class);
    }

    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

// Usage
$user = User::find(1);
$posts = $user->posts;            // collection
$post = Post::find(1);
$author = $post->user;           // single model
$post->comments()->where('approved', true)->get();

Timestamps & Soft Deletes

Timestamps

Eloquent automatically manages created_at and updated_at columns. Disable with:

class User extends Model
{
    public $timestamps = false;
}

Soft Deletes

Add a deleted_at column to your table, then use the trait:

use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
    use SoftDeletes;
}

// Now delete() sets deleted_at instead of removing the row:
$user->delete();
$user->restore();
$users = User::withTrashed()->get();
$trashed = User::onlyTrashed()->get();

Accessors & Mutators

class User extends Model
{
    // Accessor: get{Attribute}Attribute
    public function getNameAttribute($value)
    {
        return ucfirst($value);
    }

    // Mutator: set{Attribute}Attribute
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = bcrypt($value);
    }
}

// Usage:
$user->name;        // calls getNameAttribute()
$user->password = 'secret';  // calls setPasswordAttribute()

Scopes

class User extends Model
{
    public function scopeActive($query)
    {
        return $query->where('active', true);
    }

    public function scopeOfRole($query, $role)
    {
        return $query->where('role', $role);
    }
}

// Usage:
$users = User::active()->ofRole('editor')->get();

Pagination

$users = User::paginate(15);
// or
$users = User::where('active', true)->simplePaginate(10);

// In your view:
{{$users->links()}}

The page query parameter is automatically resolved by the framework's ControllerDispatcher.

Raw Queries

For raw SQL, use the DB facade:

use Simple\Database\DB;

$users = DB::select('SELECT * FROM users WHERE active = ?', [true]);

DB::insert('INSERT INTO users (name, email) VALUES (?, ?)', ['John', '[email protected]']);

DB::update('UPDATE users SET points = points + 1 WHERE id = ?', [1]);

DB::delete('DELETE FROM users WHERE active = ?', [false]);

// Transactions
DB::transaction(function () {
    DB::update('UPDATE accounts SET balance = balance - 100 WHERE id = ?', [1]);
    DB::update('UPDATE accounts SET balance = balance + 100 WHERE id = ?', [2]);
});

Model Events / Observers

Eloquent fires lifecycle events on every model operation. See the Model Observers docs for how to hook into them.