NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

Dva traity pre vlastné Eloquent modely vášho balíka: jeden necháva primárny kľúč modelu riadiť konfiguráciou, druhý zapisuje časové pečiatky v UTC bez ohľadu na časové pásmo hostiteľa.

HasConfigurableKey

RoundlyConsulting\PackageToolkit\Concerns\HasConfigurableKey riadi vlastný primárny kľúč modelu konfiguračným kľúčom <pkg>.primary_key_type, takže model zodpovedá stĺpcu, ktorý pre rovnakú hodnotu vytvorila vaša migrácia. Model kľúč pomenuje v primaryKeyTypeConfigKey():

use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\PackageToolkit\Concerns\HasConfigurableKey;

final class Ticket extends Model
{
    use HasConfigurableKey;

    protected function primaryKeyTypeConfigKey(): string
    {
        return 'tickets.primary_key_type';
    }
}
// config/tickets.php
return [
    'primary_key_type' => 'bigint',   // bigint | uuid | ulid — the type of the package's own ids
];
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use RoundlyConsulting\PackageToolkit\Enums\KeyType;

// The migration emits the matching column from the same key.
$primary = KeyType::fromConfig('tickets.primary_key_type');

Schema::create('tickets', function (Blueprint $table) use ($primary): void {
    match ($primary) {
        KeyType::BigInt => $table->id(),
        KeyType::Uuid => $table->uuid('id')->primary(),
        KeyType::Ulid => $table->ulid('id')->primary(),
    };
    // …
});
<pkg>.primary_key_typeStĺpec (vaša migrácia)Model
Nenastavená alebo 'bigint'$table->id()Autoinkrement, getKeyType() = int — akoby trait nebol použitý.
'uuid'$table->uuid('id')->primary()Časovo usporiadané UUIDv7 vytvorené pri prvom uložení modelu, getKeyType() = string, bez autoinkrementu.
'ulid'$table->ulid('id')->primary()ULID vytvorený pri prvom uložení modelu, getKeyType() = string, bez autoinkrementu.
Čokoľvek iné ('uiid')—Pri vytvorení inštancie modelu vyhodí InvalidConfigurationException.

Ide o prichádzajúci kľúč: vlastné id balíka, na ktoré ukazujú polymorfné stĺpce iných balíkov. Líši sa od odchádzajúceho kľúča — <pkg>.key_type, čítaného cez KeyType::fromConfig() —, teda typu hostiteľských modelov, na ktoré váš balík odkazuje (pozrite Typy kľúčov a schémové makrá). Oba sa nastavujú samostatne.

ČlenČo robí
abstract protected primaryKeyTypeConfigKey(): stringImplementujete ho vy: konfiguračný kľúč, ktorý určuje typ.
configuredKeyType(): KeyTypeNastavený typ, prečítaný cez KeyType::fromConfig(): nenastavený je bigint, ' ULID ' sa číta ako ulid, preklep vyhodí výnimku.
newUniqueId(): stringStr::uuid7() pri uuid, Str::ulid() pri ulid. Pri bigint sa nikdy nevolá — tie vytvára databáza.
initializeHasUniqueStringIds(): voidPri bigint vypne HasUniqueStringIds z Laravelu.
isValidUniqueId(mixed $value): boolProtected. Pri ulid ULID, inak UUID ľubovoľnej verzie, takže sa nájde aj id, ktoré hostiteľ nastavil sám.

Typ sa číta cez KeyType::fromConfig(): nenastavený je bigint, hodnota sa oreže a porovná bez ohľadu na veľkosť písmen a preklep vyhodí výnimku hneď pri vytvorení inštancie modelu, namiesto toho, aby vznikol nesprávny kľúč:

// config('tickets.primary_key_type') === 'uiid' — a typo
new Ticket;
// throws InvalidConfigurationException:
// Configuration value [tickets.primary_key_type] must be one of [bigint, uuid, ulid] (case-insensitive), [uiid] given.
  • Ako to funguje: HasUniqueStringIds z Laravelu riadi getKeyType(), getIncrementing(), uniqueIds() aj validáciu pri route bindingu jediným príznakom usesUniqueIds. Trait ho nastaví vo svojom inicializátore, takže pri bigint sa model správa presne tak, akoby trait nikdy nepoužil.
  • Časovo usporiadané kľúče: UUIDv7 aj ULID sa radia podľa času vzniku, takže latest('id') aj spracovanie po dávkach podľa id zachovajú poradie vzniku.
  • Route binding odmietne chybný kľúč ešte pred SQL. Pri uuid a ulid kľúč z routy, ktorý nie je UUID (alebo ULID), vyhodí ModelNotFoundException — 404 — namiesto toho, aby sa dostal do databázy. Záleží na tom pri PostgreSQL, kde natívny stĺpec uuid odpovie na 'not-a-key' chybou invalid input syntax for type uuid, teda 500. ULID poslaný modelu s uuid a UUID poslané modelu s ulid sa odmietnu rovnako.
  • Id, ktoré nastavíte sami, zostane: kľúč sa vytvorí len vtedy, keď je id prázdne.

StoresUtcTimestamps

RoundlyConsulting\PackageToolkit\Concerns\StoresUtcTimestamps nastaví „teraz“ modelu na UTC: created_at / updated_at, touch(), soft delete a všetko ostatné, čo Eloquent zapisuje cez freshTimestamp() / freshTimestampString(). Hostiteľ na America/New_York potom ukladá rovnaké okamihy ako hostiteľ na UTC:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use RoundlyConsulting\PackageToolkit\Concerns\StoresUtcTimestamps;

final class Delivery extends Model
{
    use SoftDeletes;
    use StoresUtcTimestamps;
}
Hostiteľ na America/New_York, o 06:30:15 UTCUložené created_at
Bez traitu (predvolené správanie Laravelu)2026-03-08 01:30:15 — miestny čas hostiteľa
So StoresUtcTimestamps2026-03-08 06:30:15
  • Mení sa len časové pásmo. freshTimestamp() vracia Date::now('UTC'): rovnaký okamih vrátane mikrosekúnd, v triede dátumu hostiteľa — Date::use(CarbonImmutable::class) dá CarbonImmutable. Presnosť stĺpca naďalej určuje formát dátumu modelu.
  • Stĺpce čítajte späť tiež ako UTC. Trait rieši zápis, nemení spôsob, akým Eloquent číta. Predvolený cast datetime prečíta uložené 06:30:15 v app.timezone, čo je na hostiteľovi mimo UTC nesprávny okamih — stĺpce pretypujte castom, ktorý číta v UTC, alebo nechajte hostiteľa bežať na app.timezone = UTC.

Oba traity sú otestované na SQLite aj PostgreSQL: kľúče bigint, uuid a ulid, odmietnutie kľúča z routy oproti natívnemu stĺpcu uuid aj spiatočná cesta v UTC.

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.