Files
rspade_system/docs/skills/model-enums/SKILL.md
root 1b46c5270c Add skills documentation and misc updates
Add form value persistence across cache revalidation re-renders

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-29 04:38:06 +00:00

6.2 KiB
Executable File

name, description
name description
model-enums Implementing model enums in RSX with integer-backed values, constants, labels, and custom properties. Use when adding enum fields to models, working with status_id or type_id columns, accessing enum labels/properties via BEM-style syntax, or populating dropdowns with enum values.

RSX Model Enums

Integer-backed enums with model-level mapping to constants, labels, and custom properties. Uses BEM-style double underscore naming for magic properties.

Defining Enums

class Project_Model extends Rsx_Model_Abstract {
    public static $enums = [
        'status_id' => [
            1 => ['constant' => 'STATUS_ACTIVE', 'label' => 'Active', 'badge' => 'bg-success', 'order' => 1],
            2 => ['constant' => 'STATUS_ON_HOLD', 'label' => 'On Hold', 'badge' => 'bg-warning', 'order' => 2],
            3 => ['constant' => 'STATUS_ARCHIVED', 'label' => 'Archived', 'selectable' => false, 'order' => 99],
        ],
        'priority_id' => [
            1 => ['constant' => 'PRIORITY_LOW', 'label' => 'Low', 'color' => '#999', 'days' => 30],
            2 => ['constant' => 'PRIORITY_MEDIUM', 'label' => 'Medium', 'color' => '#f90', 'days' => 14],
            3 => ['constant' => 'PRIORITY_HIGH', 'label' => 'High', 'color' => '#f00', 'days' => 7],
        ],
    ];
}

Required Properties

Property Purpose
constant Static constant name (generates Model::STATUS_ACTIVE)
label Human-readable display text

Special Properties

Property Default Purpose
order 0 Sort position in dropdowns (lower first)
selectable true Include in dropdown options

Non-selectable items are excluded from field__enum_select() but still display correctly when they're the current value.

Custom Properties

Add any properties for business logic - they become accessible via BEM-style syntax:

'status_id' => [
    1 => [
        'constant' => 'STATUS_ACTIVE',
        'label' => 'Active',
        'badge' => 'bg-success',           // CSS class
        'icon' => 'fa-check',              // Icon class
        'can_edit' => true,                // Business rule
        'permissions' => ['edit', 'view'], // Permission list
    ],
],

PHP Usage

// Set using constant
$project->status_id = Project_Model::STATUS_ACTIVE;

// BEM-style property access (field__property)
echo $project->status_id__label;       // "Active"
echo $project->status_id__badge;       // "bg-success"
echo $project->status_id__icon;        // "fa-check"

// Business logic flags
if ($project->status_id__can_edit) {
    // Allow editing
}

JavaScript Usage

Static Constants

project.status_id = Project_Model.STATUS_ACTIVE;

Instance Property Access

const project = await Project_Model.fetch(1);
console.log(project.status_id__label);  // "Active"
console.log(project.status_id__badge);  // "bg-success"

Static Enum Methods

All use BEM-style double underscore (field__method()):

// Get all enum data
Project_Model.status_id__enum()
// Returns: {1: {label: 'Active', badge: 'bg-success', ...}, 2: {...}, ...}

// Get specific enum's metadata by ID
Project_Model.status_id__enum(Project_Model.STATUS_ACTIVE)
// Returns: {label: 'Active', badge: 'bg-success', order: 1, ...}

Project_Model.status_id__enum(2).selectable  // true or false

// For dropdown population (respects 'selectable' and 'order')
Project_Model.status_id__enum_select()
// Returns: [{value: 1, label: 'Active'}, {value: 2, label: 'On Hold'}]
// Note: Archived excluded because selectable: false

// Simple id => label map
Project_Model.status_id__enum_labels()
// Returns: {1: 'Active', 2: 'On Hold', 3: 'Archived'}

// Array of valid IDs
Project_Model.status_id__enum_ids()
// Returns: [1, 2, 3]

Template Usage

<span class="badge <%= this.args.project.status_id__badge %>">
    <%= this.args.project.status_id__label %>
</span>

<Select_Input
    $name="status_id"
    $options="<%= JSON.stringify(Project_Model.status_id__enum_select()) %>"
/>

Boolean Fields

For boolean fields, use 0/1 as keys:

'is_verified' => [
    0 => ['constant' => 'NOT_VERIFIED', 'label' => 'Not Verified', 'icon' => 'fa-times'],
    1 => ['constant' => 'VERIFIED', 'label' => 'Verified', 'icon' => 'fa-check'],
]

Context-Specific Labels

Define different labels for different contexts:

1 => [
    'constant' => 'STATUS_NEW',
    'label' => 'New Listing',           // Backend/default
    'label_frontend' => 'Coming Soon',  // Public-facing
    'label_short' => 'New',             // Abbreviated
]

Access: $item->status__label_frontend


Permission Systems

Use custom properties for complex permission logic:

'role_id' => [
    1 => [
        'constant' => 'ROLE_ADMIN',
        'label' => 'Administrator',
        'permissions' => ['users.create', 'users.delete', 'settings.edit'],
        'can_admin_roles' => [2, 3, 4],  // Can manage these role IDs
    ],
    2 => [
        'constant' => 'ROLE_MANAGER',
        'label' => 'Manager',
        'permissions' => ['users.view', 'reports.view'],
        'can_admin_roles' => [3, 4],
    ],
]
// Check permissions
if (in_array('users.create', $user->role_id__permissions)) {
    // User can create users
}

Anti-Aliasing Policy

NEVER alias enum properties in fetch() - the BEM-style naming exists for grepability:

// WRONG - Aliasing obscures data source
$data['type_label'] = $record->type_id__label;  // BAD

// RIGHT - Use full BEM-style names in JavaScript
contact.type_id__label  // Good - grepable, self-documenting

The fetch() function's purpose is SECURITY (removing private data), not aliasing.


Database Migration

Always use BIGINT for enum columns:

$table->bigInteger('status_id')->default(Project_Model::STATUS_ACTIVE);

Never use:

  • VARCHAR (wastes space)
  • MySQL ENUM type (inflexible)
  • TINYINT (too small for future expansion)

After Adding Enums

Run model documentation generator:

php artisan rsx:migrate:document_models

This updates the model's documentation comments with enum information.

More Information

Details: php artisan rsx:man enum