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

  • Pros:

    • Lightweight & Non-Intrusive: The package leverages Eloquent relationships without requiring schema migrations for each flag, reducing database complexity.
    • Idempotency-First Design: Aligns perfectly with workflows requiring restartable, stateful processes (e.g., batch jobs, migrations, or multi-step user flows).
    • Query Scopes: Built-in flagged()/notFlagged() scopes enable efficient bulk operations, critical for scaling.
    • Laravel-Native: Integrates seamlessly with Eloquent’s ORM, reducing learning curves for PHP/Laravel teams.
    • Extensible: Supports enums (since v1.4.0) and array-based unflagging (v1.5.0), accommodating evolving requirements.
  • Cons:

    • Single-Table Inheritance (STI) Limitation: Flags are tied to model instances via a flags table, which may complicate polymorphic relationships or STI hierarchies.
    • No Native TTL: Flags persist indefinitely unless manually deleted; requires additional logic for expiration (e.g., via Laravel Queues or Cron).
    • Concurrency Risks: High-frequency flag toggling (e.g., in real-time systems) could lead to race conditions without explicit locking.

Integration Feasibility

  • Prerequisites:
    • Laravel 11+ (or 10+ with backports) due to Eloquent query builder dependencies.
    • PHP 8.0+ (per v1.0.1 changelog).
    • Existing Eloquent models to attach flags to (no impact on non-Eloquent models).
  • Dependencies:
    • Minimal: Only requires spatie/laravel-model-flags and Laravel’s core.
    • No external services (e.g., Redis) unless extending functionality (e.g., caching flag checks).
  • Database Impact:
    • Adds a flags table with model_id, name, and timestamps.
    • Migration Path: Zero-downtime if using Laravel’s schema migrations (published via vendor:publish).

Technical Risk

  • Low-Medium:
    • Performance: Flag queries add a join to the flags table. Benchmark with DB::enableQueryLog() to validate impact on high-traffic endpoints.
    • Schema Changes: Migration is idempotent but requires migrate execution (test in staging first).
    • Flag Naming Collisions: No built-in namespace for flags; enforce conventions (e.g., user_* prefixes) to avoid clashes.
    • Testing Gaps:
      • No built-in flag expiration or soft-deletes (implement custom logic if needed).
      • Race conditions in high-concurrency scenarios (mitigate with database transactions or queues).

Key Questions

  1. Use Case Alignment:
    • Are flags primarily for idempotent workflows (e.g., batch jobs) or dynamic state tracking (e.g., user preferences)?
    • If the latter, consider alternatives like JSON columns or dedicated settings tables.
  2. Scalability:
    • Will flag queries scale with model volume? Test with User::flagged('x')->count() on large datasets.
  3. Maintenance:
    • How will flag names be managed? (e.g., constants, config files, or a flags table metadata?)
  4. Auditability:
    • Are flag changes auditable? Extend with Laravel Audit or custom logs if needed.
  5. Alternatives:
    • Compare with spatie/laravel-activitylog (for audit trails) or spatie/laravel-medialibrary (for metadata).

Integration Approach

Stack Fit

  • Ideal For:
    • Laravel Monoliths: Zero friction with Eloquent; no framework changes required.
    • Serverless/Queued Jobs: Perfect for idempotent Artisan commands or queue workers (e.g., SendPromotionMail).
    • Progress Tracking: UI dashboards showing flagged/unflagged models (e.g., "Users awaiting onboarding").
  • Less Suited For:
    • Non-Laravel Backends: Requires PHP/Laravel integration.
    • High-Volume Real-Time Systems: Risk of flag table bloat; consider Redis for ephemeral flags.

Migration Path

  1. Pre-Integration:
    • Assess Models: Identify 2–3 candidate models to pilot flags (e.g., User, Order).
    • Define Flag Naming: Agree on conventions (e.g., user_verified_email, order_shipped).
    • Test Migration: Run php artisan vendor:publish --tag="model-flags-migrations" in a staging DB.
  2. Implementation:
    • Step 1: Add trait to target models:
      use Spatie\ModelFlags\Models\Concerns\HasFlags;
      class User extends Model { use HasFlags; }
      
    • Step 2: Publish config (optional) to customize flag_model.
    • Step 3: Run migrations.
  3. Validation:
    • Unit Tests: Verify hasFlag(), flag(), and scopes.
    • Load Test: Simulate 10K flag operations to check performance.
    • Rollback Plan: Document flags table deletion (if needed).

Compatibility

  • Laravel Versions: Officially supports 11–13 (backported to 10 via PRs).
  • PHP Versions: 8.0+ (test with php -v before integration).
  • Database: MySQL, PostgreSQL, SQLite (via Eloquent).
  • Conflicts:
    • Model Events: Flags auto-delete on model deletion (since v1.1.0); override deleted() if needed.
    • Caching: Flag checks bypass cache unless manually cached (e.g., Cache::remember()).

Sequencing

  1. Phase 1: Pilot with non-critical models (e.g., TestModel).
  2. Phase 2: Integrate into core workflows (e.g., User flags for feature rollouts).
  3. Phase 3: Optimize:
    • Add indexes to flags.name if querying by flag name frequently.
    • Cache frequent flag checks (e.g., Cache::forever() for static flags).
  4. Phase 4: Monitor:
    • Track flags table growth (alert if >1M rows).
    • Log slow queries (e.g., DB::listen()).

Operational Impact

Maintenance

  • Proactive Tasks:
    • Flag Cleanup: Schedule periodic pruning of stale flags (e.g., Flag::where('updated_at', '<', now()->subYear())->delete()).
    • Naming Audits: Review flag names quarterly for consistency.
    • Dependency Updates: Monitor Laravel/Eloquent breaking changes (e.g., query builder syntax).
  • Reactive Tasks:
    • Flag Collisions: Implement a FlagExists exception or use try-catch for idempotent operations.
    • Performance Degradation: Optimize queries or archive old flags if flags table grows >10GB.

Support

  • Troubleshooting:
    • Common Issues:
      • "Flag not found": Verify model ID and flag name case sensitivity.
      • Slow queries: Add indexes or use with() to eager-load flags.
    • Debugging Tools:
      • DB::enableQueryLog() to inspect flag-related queries.
      • Tinker to test flag operations:
        $user = User::first();
        $user->flag('test'); $user->hasFlag('test'); // true
        
  • Documentation:
    • Internal Wiki: Document flag naming conventions, ownership, and cleanup policies.
    • Runbook: Include steps to reset all flags (e.g., Flag::truncate()).

Scaling

  • Horizontal Scaling:
    • Read Replicas: Flag queries are read-heavy; ensure replicas are synced.
    • Sharding: If flags table exceeds 100M rows, consider sharding by model_id ranges.
  • Vertical Scaling:
    • Database: Monitor flags table size; optimize indexes if queries time out.
    • Caching: Cache flag checks for static flags (e.g., is_feature_enabled).
  • Alternatives at Scale:
    • Redis: Store flags in Redis for low-latency access (requires custom implementation).
    • Event Sourcing: Replace flags with event logs for auditability.

Failure Modes

Failure Scenario Impact Mitigation
Database downtime Flags inaccessible Use transactions; implement retry logic.
Flag table corruption Lost flags Regular backups; test restore procedures.
Concurrent flag updates Race conditions (e.g., double flags) Use database transactions or queues.
Unbounded flag proliferation Table bloat, slow queries Enforce TTL or cleanup policies.
Flag naming collisions Overwritten flags Enforce namespacing
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai