Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Model Flags Laravel Package

spatie/laravel-model-flags

Add lightweight “flags” to Eloquent models via a trait—store process state without extra columns. Check, set, and clear flags, and query with flagged/notFlagged scopes. Ideal for idempotent, restartable jobs like one-time emails or migrations.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Idempotency & State Management: Perfect fit for workflows requiring idempotency (e.g., batch processing, retries, or long-running tasks). Eliminates race conditions by tracking state via flags instead of manual checks.
  • Decoupled State Storage: Avoids schema migrations for simple boolean state, reducing database complexity. Flags are stored in a dedicated flags table, isolating state from core model data.
  • Query Flexibility: Provides Eloquent scopes (flagged(), notFlagged()) for efficient bulk operations, leveraging Laravel’s query builder.
  • Extensibility: Supports enums (since v1.4.0) and array-based unflagging (v1.5.0), accommodating complex use cases without forking.

Integration Feasibility

  • Laravel-Centric: Designed for Laravel’s Eloquent ORM, with zero configuration required beyond trait usage. Minimal boilerplate for adoption.
  • Database Agnostic: Works with any Laravel-supported database (MySQL, PostgreSQL, SQLite, etc.) via migrations.
  • Version Compatibility: Actively maintained for Laravel 11–13 (as of 2026), with clear upgrade paths. Backward-compatible with PHP 8.0+.

Technical Risk

  • Performance Overhead:
    • Flag Lookups: Each hasFlag() or flag() operation triggers a database query. For high-frequency checks (e.g., per-request), consider caching (e.g., Redis) or batching.
    • Table Bloat: Unbounded flags per model could inflate the flags table. Mitigate with:
      • Flag expiration (custom logic to purge old flags).
      • Soft deletes for flags (if using Laravel’s soft deletes).
  • Concurrency: No built-in locking for flag operations. In high-contention scenarios (e.g., distributed batch jobs), add DB::transaction() or optimistic locking ($model->fresh()).
  • Schema Dependencies: Requires the flags table, which may conflict with existing projects using similar patterns (e.g., model_state tables). Audit for overlaps pre-integration.

Key Questions

  1. Use Case Alignment:
    • Are flags replacing existing state columns (e.g., is_processed) or augmenting them? If replacing, assess migration effort.
    • Will flags be used for temporal tracking (e.g., lastFlaggedAt()) or just binary state?
  2. Scalability:
    • Expected volume of flags per model? For >100 flags/model, evaluate if a serialized JSON column (e.g., flags:array) might be simpler.
    • Will bulk flag operations (e.g., Flag::where()->delete()) impact performance during maintenance?
  3. Observability:
    • How will flag state be monitored? Consider adding a flagged_at column to the flags table for auditing.
    • Are there compliance requirements for flag history (e.g., immutable logs)?
  4. Team Adoption:
    • Is the team familiar with Laravel’s Eloquent traits? Minimal training needed, but document the flags table schema for DBAs.
    • Will developers need to enforce flag naming conventions (e.g., snake_case) to avoid collisions?

Integration Approach

Stack Fit

  • Laravel Ecosystem: Native integration with Eloquent, Artisan, and Laravel’s query builder. No framework-specific hacks required.
  • PHP Version: Supports PHP 8.0+, aligning with Laravel’s LTS support. No polyfills needed.
  • Database: Works with any Laravel-supported database. Test migrations for your DB’s quirks (e.g., PostgreSQL’s jsonb vs. MySQL’s json).
  • Testing: Compatible with Pest/PHPUnit. Mock the HasFlags trait for unit tests:
    $model->shouldReceive('flags')->andReturn(new FlagCollection());
    

Migration Path

  1. Assessment Phase:
    • Audit existing state management (e.g., boolean columns, status enums). Identify candidates for flag replacement.
    • Review current batch job patterns (e.g., whereNull('processed_at')) to estimate idempotency gains.
  2. Pilot Integration:
    • Start with a single model (e.g., User) and 2–3 flags for a proof-of-concept.
    • Example: Replace is_email_verified column with hasFlag('email_verified').
  3. Migration Steps:
    • Schema: Publish and run migrations (php artisan vendor:publish --tag="model-flags-migrations").
    • Models: Add use HasFlags to target models. For existing records, seed flags via a seeder or data migration:
      User::where('is_email_verified', true)->get()->each(fn($u) => $u->flag('email_verified'));
      
    • Queries: Replace raw SQL/Eloquent queries with scopes:
      // Before: User::whereNull('processed_at')->get();
      // After:  User::notFlagged('processed')->get();
      
    • Jobs/Commands: Update idempotent logic to use flags:
      User::notFlagged('sent_invoice')
          ->chunk(100, fn($users) => Invoice::send($users)->each(fn($u) => $u->flag('sent_invoice')));
      
  4. Deprecation:
    • Phase out old state columns post-migration (e.g., add is_deprecated = true to columns).

Compatibility

  • Laravel Services: Works alongside Laravel’s caching (e.g., cache flag results for read-heavy apps), queue workers, and events.
  • Third-Party Packages:
    • Spatie Packages: Plays well with other Spatie packages (e.g., laravel-activitylog) if using their flagging patterns.
    • Event Sourcing: Flags can trigger events (e.g., Flagged/Unflagged), but requires custom event listeners.
  • Legacy Code: Use trait aliases or interfaces to mock HasFlags in legacy systems:
    interface Flaggable { public function flag(string $name): void; }
    

Sequencing

  1. Core Integration:
    • Start with models used in critical workflows (e.g., user onboarding, payments).
  2. Batch Processing:
    • Prioritize long-running jobs (e.g., report generation, data imports) for idempotency gains.
  3. Query Optimization:
    • Add indexes to the flags table if querying by name or flaggable_id:
      Schema::table('flags', function (Blueprint $table) {
          $table->index(['name', 'flaggable_id']);
      });
      
  4. Monitoring:
    • Instrument flag operations with Laravel Telescope or custom logging to track usage patterns.

Operational Impact

Maintenance

  • Schema Management:
    • The flags table is self-contained but requires manual updates for new columns (e.g., adding description to flags). Use migrations for changes.
    • Backup Strategy: Include the flags table in database backups. Consider point-in-time recovery for critical flags.
  • Flag Housekeeping:
    • Implement a scheduled job to purge stale flags (e.g., older than 2 years):
      Flag::where('updated_at', '<', now()->subYears(2))->delete();
      
    • For soft deletes, add a deleted_at column to the flags table and override the delete() method in the Flag model.
  • Configuration:
    • Customize the flag_model in config/model-flags.php if extending the Flag model (e.g., adding metadata).

Support

  • Troubleshooting:
    • Flag Not Persisting: Verify the model uses HasFlags and the flags table exists. Check for transaction rollbacks.
    • Performance Issues: Use DB::enableQueryLog() to profile flag queries. Optimize with:
      • Batch flag operations (e.g., User::notFlagged('x')->get()).
      • Caching flag checks for read-heavy apps:
        $hasFlag = Cache::remember("user_{$user->id}_flag_receivedMail", now()->addHours(1), fn() => $user->hasFlag('receivedMail'));
        
    • Data Corruption: Ensure the flaggable_id and flaggable_type columns in the flags table match your model’s primary key and class name.
  • Documentation:
    • Maintain a runbook for:
      • Flag naming conventions (e.g., domain_process).
      • Common queries (e.g., "How to find all users flagged in the last 7 days?").
      • Rollback procedures (e.g., reverting to boolean columns).

Scaling

  • Horizontal Scaling:
    • Flags are stateless and database-backed, so they scale with your Laravel app. No distributed coordination needed.
    • For multi-DC setups, ensure the flags table is replicated synchronously.
  • Vertical Scaling:
    • Monitor `
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony