codelieutenant/laravel-pgenum

Laravel 迁移中使用的 Postgres 枚举

v1.0.0 2024-04-20 20:27 UTC

This package is auto-updated.

Last update: 2024-09-20 09:36:49 UTC


README

Laravel 对 Postgres 实际枚举的回应

Tests GitHub issues GitHub stars GitHub license GitHub Sponsors GitHub commit activity

灵感

在 Laravel 的迁移中,枚举已经存在,对吧?是的,但是并不完全。这些枚举并不是真正的数据库枚举。这些枚举只是具有 CHECK 约束的字符串类型。所以我对自己说,使用真正的 Postgres 枚举在 Laravel 中会非常棒。

入门指南

安装

composer require codelieutenant/laravel-pgenum

在迁移中使用

Schema API

此库通过 Illuminate\Support\Facades\Schema 扩展 Laravel,使用 Illuminate\Support\Traits\Macroable

Schema::createEnum(string $name, ?array $values = null);
Schema::createEnumIfNotExists((string $name, ?array $values = null);

Schema::addEnumValue(string $type, string $value, ?Direction $direction = null, ?string $otherValue = null, bool $ifNotExists = true);
Schema::renameEnumValue(string $type, string $oldName, string $newName);

Schema::dropEnum(string $name);
Schema::dropEnumIfExists(string $name);

Schema API 默认也支持 PHP 枚举

enum MyEnum: string
{
    case MyValue = 'value';
}

// Migrations
// Generated SQL
// CREATE TYPE my_enum ENUM ('value');
Schema::createEnum(MyEnum::class);

// Generated SQL
// CREATE TYPE my_enum ENUM ('value');
Schema::dropEnum(MyEnum::class);
Blueprint API

对于 Blueprint,只有一个函数 enumeration 用于在表中创建列。

// Accepts PHP Enums and Strings
\Illuminate\Database\Schema\Blueprint::enumeration(string $name);

完整的迁移示例

public function up(): void
{
    // Postgres Enums must be known before Table is created
    // This is my, `createEnum` must be seperated and before `Schema::create`
    Schema::createEnum(MyEnum::class);
    Schema::create('users', function(Blueprint $table) {
        $table->id();
        $table->enumeration(MyEnum::class);   
    });
}

public function down(): void
{
    Schema::dropEnum(MyEnum::class);
}

使用 PHP 枚举

Laravel 默认支持 PHP 枚举,但此库需要比 Laravel 默认提供的更多。支持所有形式的 PHP 枚举(-> 基于字符串/整数,非基于)的枚举,以下是一个示例

use \Illuminate\Database\Eloquent\Model;
use \CodeLieutenant\LaravelPgEnum\Casts\EnumCast;

enum Role : string
{
    case Admin = 'admin';
    case User = 'user'; 
}

class User extends Model
{
    // For Laravel < 11.0 use $casts property
    public function casts(): array
    {
        return [
            // This is supported by default
            // as long as PHP Enum is backed by string
            'role' => Role::class,
            
            // For non-backed/int backed PHP Enums
            // custom converter is needed, this also
            // can be applied to string backed enums (but not needed)
            // This is due to the limitation of Postgres Enums
            // as it requires values to be string named, and not INTs
            // Using Role::class as example, can be any other PHP Enum
            'non_string_backed_enum' => EnumCast::class ':' . Role::class
        ];    
    }
}