spatie/laravel-model-flags

repository·main·Indexed 19 days ago

https://github.com/spatie/laravel-model-flags

A Laravel package that allows adding arbitrary flags to Eloquent models without adding new columns via migrations. It provides the HasFlags trait for managing flags on model instances, Eloquent scopes for filtering models by flags, and is designed for tracking process states and building idempotent background tasks.

Tokens
1.1K
Snippets
7
Records
7
Agent score
16%

What's inside laravel-model-flags

  1. Install Laravel Model Flags

    main

    Install the package via Composer and set up the required database table for storing flags.

    composer require spatie/laravel-model-flags
    
    # Publish and run the migrations to create the `flags` table
    php artisan vendor:publish --tag="model-flags-migrations"
    php artisan migrate
  2. Add flags to Eloquent models

    main

    To enable flag functionality on an Eloquent model, include the Spatie\ModelFlags\Models\Concerns\HasFlags trait in your model class.

    use Illuminate\Database\Eloquent\Model;
    use Spatie\ModelFlags\Models\Concerns\HasFlags;
    
    class YourModel extends Model
    {
        use HasFlags;
    }
  3. Configure the flag model

    main

    You can optionally publish the configuration file to customize which model is used to represent flags. By default, it uses Spatie\ModelFlags\Models\Flag.

    php artisan vendor:publish --tag="model-flags-config"
    return [
        /*
         * The model used as the flag model.
         */
        'flag_model' => Spatie\ModelFlags\Models\Flag::class,
    ];
  4. Use flags for idempotent processes

    main

    A primary use case is building restartable (idempotent) code, such as Artisan commands. By checking for a flag before performing an action and setting the flag immediately after, you ensure that if a process fails halfway through, subsequent runs will only process the remaining items.

    // In an Artisan command
    User::notFlagged('wasSentPromotionMail')
        ->each(function(User $user) {
            Mail::to($user->email)->send(new PromotionMail());
    
            $user->flag('wasSentPromotionMail');
        });
  5. Query models using flag scopes

    main

    The package provides Eloquent scopes to quickly filter models based on the presence or absence of a flag.

    // Get all models that have the flag
    YourModel::flagged('myFlag')->get();
    
    // Get all models that do NOT have the flag
    YourModel::notFlagged('myFlag')->get();
  6. Bulk delete flags

    main

    You can delete flags using the underlying flags relationship or by interacting with the Flag model directly.

    • To delete all flags for a specific model: $model->flags()->delete();
    • To delete a specific flag for a model: $model->flags()->where('name', 'myFlag')->delete();
    • To remove a specific flag name from ALL models in the database: Use the Flag model to delete where the name matches.
    use Spatie\ModelFlags\Models\Flag;
    
    // Remove 'myFlag' from every model in the database
    Flag::where('name', 'myFlag')->delete();
  7. Manage flags on a model instance

    main

    Once the HasFlags trait is added, you can use the following methods to manage flags on a specific model instance:

    • $model->flag('name'): Adds a flag. If the flag already exists, the updated_at timestamp is updated.
    • $model->hasFlag('name'): Returns true if the model has the specified flag.
    • $model->unflag('name'): Removes the specified flag.
    • $model->flagNames(): Returns an array of all flag names currently on the model.
    • $model->lastFlaggedAt(): Returns the updated_at timestamp of the most recently updated flag. If a name is provided, returns the timestamp for that specific flag.
    // Add and check flags
    $model->flag('myFlag');
    $model->hasFlag('myFlag'); // true
    
    // Remove a flag
    $model->unflag('myFlag');
    
    // Get all flag names
    $model->flagNames();
    
    // Check when flags were set
    $model->lastFlaggedAt();
    $model->lastFlaggedAt('myFlag');