Eloquent ORM

Last updated: 2026-10-30

Canvas Eloquent brings Laravel's standalone Eloquent ORM into Canvas. It wires a single database connection into both Canvas's dependency injection container and Eloquent's own static connection resolver, so plain Eloquent models work with no additional setup.

explanation

Core Concepts

  • Capsule — Illuminate's standalone database bootstrap (Illuminate\Database\Capsule\Manager), used outside a full Laravel application. The package builds and caches one Capsule instance per process.
  • Eager boot — the Capsule is built and bootEloquent() is called the moment the package's configuration is applied, during Canvas's normal container setup. Nothing needs to type-hint ConnectionInterface for Eloquent models to work.
  • Single connection — this package manages exactly one database connection, read from config/eloquent.php. Multiple named connections are not supported.
  • ConnectionInterface — Illuminate\Database\ConnectionInterface is also registered with Canvas's DI container, for code that wants Eloquent's query builder without using full Eloquent models.

Installation

Install via Composer:

composer require quellabs/canvas-eloquent

Then publish the configuration file:

sculpt eloquent:init

Edit config/eloquent.php with your database credentials.

Configuration

All options with their defaults:

// config/eloquent.php
return [
    'driver'    => 'mysql',               // mysql, pgsql, sqlite, sqlsrv
    'host'      => 'localhost',
    'database'  => '',
    'username'  => '',
    'password'  => '',
    'port'      => 3306,
    'charset'   => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix'    => '',
];

Any key you omit falls back to the default shown above.

Quick Start

Two ways to work with your database, depending on how much of Eloquent you want: full models or the query builder.

Eloquent Models

Once config/eloquent.php exists, any plain Eloquent model works immediately — no constructor injection, no manual bootstrapping:

use Illuminate\Database\Eloquent\Model;

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

class BlogController {
    public function index(): Response {
        $posts = Post::where('published', true)->orderBy('id')->get();

        return $this->render('blog/index.tpl', compact('posts'));
    }
}
Note: this works because Canvas's DI container applies this package's configuration to its service provider during container construction, regardless of whether anything resolves ConnectionInterface. That's enough to boot Eloquent's static connection resolver before any controller runs.

Query Builder via DI

For code that prefers Eloquent's fluent query builder without a model class, type-hint ConnectionInterface:

use Illuminate\Database\ConnectionInterface;

class ReportController {
    public function __construct(
        private ConnectionInterface $db
    ) {}

    public function index(): Response {
        $rows = $this->db->table('posts')
            ->where('published', true)
            ->orderBy('id')
            ->get(['id', 'title']);

        return $this->json(['posts' => $rows]);
    }
}

Sculpt CLI Commands

CommandDescription
sculpt eloquent:initPublish config/eloquent.php to the project root (skips if it already exists)