Appearance
Models & Keys
FilamentCraft ships ten Eloquent models. You can pick their primary key type and swap any of them for your own subclass.
Primary key type
Choose it at install:
bash
php artisan filamentcraft:install --keys=uuidWithout --keys, an interactive install asks, preselecting your User model's key type. The choice is written to config/filamentcraft.php:
php
'database' => [
'key_type' => 'uuid', // int (default) | uuid | ulid
],key_type | Primary keys | Column |
|---|---|---|
int | Auto-incrementing integers | bigint unsigned |
uuid | Ordered UUIDs, generated on create | uuid (native on Postgres, char(36) on MySQL) |
ulid | Lowercase ULIDs, generated on create | char(26) |
It covers every FilamentCraft table and every key between them. The models generate the ids, so you don't need to add HasUuids to anything. It works the same on SQLite, MySQL/MariaDB and PostgreSQL.
Set it before the first migrate
The migrations read key_type when they create the tables. Changing it afterwards doesn't convert them. filamentcraft:doctor fails when the config and the tables disagree. Existing installs keep integer keys.
Owner and user columns
filamentcraft_sites.owner_id and the user_id columns point at your models, so they are typed after those models, not after key_type:
- Owner:
tenancy.owner_model, else your panel's tenant model. - User:
auth.providers.users.model.
HasUuids and HasUlids models get uuid and ulid columns. Integer models get bigint. Other string keys get a string column. Set the type yourself when detection can't see the model at migrate time:
php
'database' => [
'key_type' => 'uuid',
'owner_key_type' => 'uuid',
'user_key_type' => 'int',
],Your own model classes
Extend a model to add traits, casts, relations, scopes or observers:
bash
php artisan make:filamentcraft-model SiteThis writes app/Models/FilamentCraft/Site.php and registers it in the published config:
php
namespace App\Models\FilamentCraft;
use FilamentCraft\Models\Site as BaseSite;
class Site extends BaseSite
{
//
}php
'models' => [
'site' => App\Models\FilamentCraft\Site::class,
// template, template_revision, theme, region, media,
// custom_font, redirect, section_definition, ai_usage, submission
],FilamentCraft then returns your class everywhere:
Site::query(),Site::find(),Site::create(), and static scopes such asSite::live()- Relations:
$template->site,$site->templates, andHasSite::sites()on your owner model - The Filament resources, route model binding, and the package factories
Your global scopes, casts and events apply to all of them.
php
class Site extends BaseSite
{
use Searchable;
public function invoices(): HasMany
{
return $this->hasMany(Invoice::class); // infers site_id, not custom_site_id
}
protected static function booted(): void
{
parent::booted();
static::created(fn (self $site) => Billing::openAccountFor($site));
}
}The override must:
- Extend the FilamentCraft model. Anything else throws at boot and names the config key.
- Call
parent::booted()if you definebooted(). FilamentCraft registers its own model hooks there. - Keep the table name. The package's migrations and some queries use the
filamentcraft_*names directly.filamentcraft:doctorwarns if you change$table.
Check the setup
bash
php artisan filamentcraft:doctorKey type [uuid] ........................................... OK
Model [App\Models\FilamentCraft\Site] replaces [Site] ....... OK