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 Exists Rule Laravel Package

mvanduijker/laravel-model-exists-rule

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation: Run composer require mvanduijker/laravel-model-exists-rule in your project root.
  2. Publish Config (if needed): No config file is required by default, but you can publish it with php artisan vendor:publish --provider="Duijker\LaravelModelExistsRule\ServiceProvider" for customization.
  3. First Use Case: Validate a model's existence in a form request:
    use Duijker\LaravelModelExistsRule\ModelExists;
    
    // In your FormRequest or controller
    $rules = [
        'user_id' => ['required', new ModelExists(\App\Models\User::class, 'id')],
    ];
    

Where to Look First

  • README: Focus on the "Usage" section for basic and advanced examples.
  • Tests: Check tests/ for edge cases and real-world usage patterns.
  • Source: Review src/ModelExists.php to understand customization options.

Implementation Patterns

Basic Validation Workflow

  1. Simple Existence Check:

    new ModelExists(\App\Models\User::class, 'id')
    

    Validates if a record exists in the users table with the given id.

  2. Custom Query Builder Logic:

    new ModelExists(\App\Models\Post::class, 'slug')
        ->where('published', true)
        ->whereHas('author', fn($q) => $q->where('active', true))
    

    Extend with Eloquent query methods for complex conditions.

  3. Dynamic Model/Column:

    $modelClass = $request->input('model');
    $column = $request->input('column');
    new ModelExists($modelClass, $column)
    

    Useful for polymorphic validation (e.g., admin panels).

Integration Tips

  • Form Requests: Centralize validation logic in App\Http\Requests for reusability.
  • API Resources: Combine with API responses to return model details if validation passes:
    $user = \App\Models\User::find($request->user_id);
    return new UserResource($user);
    
  • Custom Error Messages:
    new ModelExists(\App\Models\User::class, 'id')
        ->message('The selected user does not exist.'),
    

Advanced Patterns

  1. Soft Deletes:

    new ModelExists(\App\Models\Order::class, 'id')
        ->withTrashed()
    

    Include soft-deleted records in validation.

  2. Scopes:

    new ModelExists(\App\Models\Product::class, 'sku')
        ->where('category_id', $request->category_id)
        ->scope('active')
    

    Leverage model scopes for reusable query logic.

  3. Conditional Validation:

    $validator = Validator::make($request->all(), [
        'user_id' => [
            new ModelExists(\App\Models\User::class, 'id'),
            Rule::unique('users')->ignore($request->user_id), // Avoid self-validation
        ],
    ]);
    

Gotchas and Tips

Pitfalls

  1. Case Sensitivity:

    • Column names in the rule must match the database schema exactly (e.g., id vs ID).
    • Fix: Use snake_case consistently or cast columns in the rule:
      new ModelExists(\App\Models\User::class, 'ID')->castColumn('id');
      
  2. Eager Loading Pitfalls:

    • whereHas or with can trigger N+1 queries if not optimized.
    • Fix: Use withCount() or loadMissing() for performance:
      new ModelExists(\App\Models\Post::class, 'id')
          ->withCount('comments')
          ->having('comments_count', '>', 0)
      
  3. Model Events:

    • The rule executes queries but doesn’t trigger model events (e.g., retrieved). Useful for side effects like logging.
  4. Caching:

    • Repeated validations on the same model/column may hit the database unnecessarily.
    • Fix: Cache results in the request or use Laravel’s query cache:
      new ModelExists(\App\Models\User::class, 'id')
          ->useCache()
          ->cacheFor(seconds: 300);
      

Debugging

  1. Query Logs: Enable Laravel’s query logging to inspect generated SQL:

    DB::enableQueryLog();
    $validator = Validator::make([...], [...]);
    dd(DB::getQueryLog());
    
  2. Custom Validation Logic: Override the passes() method in a custom rule class if default behavior is insufficient:

    class CustomModelExists extends ModelExists {
        public function passes($attribute, $value) {
            return $this->builder->where('active', true)->exists();
        }
    }
    

Extension Points

  1. Custom Builders: Inject a pre-built query:

    $builder = \App\Models\User::query()->where('role', 'admin');
    new ModelExists($builder, 'id');
    
  2. Dynamic Model Resolution: Resolve models dynamically (e.g., from a config or service container):

    $model = app()->make($request->model_class);
    new ModelExists($model, 'id');
    
  3. Testing: Mock the rule in tests to avoid database hits:

    $rule = new ModelExists(\App\Models\User::class, 'id');
    $rule->shouldReceive('passes')->andReturn(true);
    

Config Quirks

  • Default Behavior: The rule uses exists() under the hood, which is efficient but doesn’t load the model.
  • Custom Messages: Override via language files (resources/lang) or inline:
    ->message('custom.error.message'),
    
  • Soft Deletes: Ensure your model uses SoftDeletes trait and the deleted_at column exists.

Pro Tips

  1. Combine with Other Rules:

    new ModelExists(\App\Models\User::class, 'id')
        ->sometimesRequired()
        ->when($request->has('admin'), function ($rule) {
            return $rule->where('role', 'admin');
        }),
    
  2. Bulk Validation: Validate multiple IDs at once:

    $ids = explode(',', $request->user_ids);
    $valid = collect($ids)->every(fn($id) =>
        new ModelExists(\App\Models\User::class, 'id')->passes('user_id', $id)
    );
    
  3. API Rate Limiting: Pair with throttle rules to prevent abuse:

    $rules = [
        'user_id' => [
            new ModelExists(\App\Models\User::class, 'id'),
            Rule::throttle('user-lookup', 10)->every(15),
        ],
    ];
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
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