Laravel how to validate if exists and belong to user
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Laravel: Validating Existence and Ownership – A Deep Dive
As developers working with Laravel, one of the most common scenarios we encounter is needing to validate user input not just for existence, but also for ownership. For instance, when a user tries to modify a record like a shift, we must ensure that the requested ID exists in the database and belongs to the currently authenticated user.
You correctly pointed out the basic validation:
'shift_id' => 'required|exists:shifts,id'
This tells Laravel, "Make sure this ID exists in the shifts table." However, this alone does not confirm that the logged-in user is authorized to access or modify that specific shift. To achieve true security and data integrity, we need a more advanced approach that leverages Eloquent relationships and custom validation logic.
This post will explore the most robust ways to validate if an ID exists and belongs to the authenticated user within a Laravel application.
The Challenge of Relational Validation
The core challenge lies in bridging simple input validation with complex database relationships. Simply checking exists only verifies existence; it ignores the crucial ownership link defined by the user_id column in your shifts table.
To solve this elegantly, we move beyond standard built-in rules and implement custom logic that interacts directly with the Eloquent models. This keeps our validation layer clean while ensuring security.
Solution 1: Implementing a Custom Validation Rule
The most "Laravel" way to handle complex, multi-condition validation is by creating a custom rule within your Request class or Validator setup. This approach centralizes the business logic into reusable components.
First, ensure you have a relationship defined in your models (e.g., User has many shifts).
Step 1: Define the Custom Rule
We will create a rule that checks both conditions simultaneously. This rule will inspect the database to see if a shift with the given ID exists and if its associated user_id matches the authenticated user's ID.
// In your App\Rules directory, or directly in a service class
namespace App\Rules;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
class ShiftBelongsToUserRule
{
/**
* Determine if the shift belongs to the authenticated user.
*
* @param string $shiftId
* @return bool
*/
public function passes($attribute, $value)
{
// 1. Check if the shift exists and belongs to the currently logged-in user
$shift = \App\Models\Shift::where('id', $value)
->where('user_id', Auth::id())
->first();
return (bool) $shift;
}
/**
* Get the failed message.
*
* @return string
*/
public function message()
{
return 'The selected shift does not exist or does not belong to you.';
}
}
Step 2: Applying the Rule in the Request
Now, we integrate this custom rule into our form request. This ensures that if a user tries to submit an ID that doesn't match their ownership criteria, validation will fail immediately.
// In your Form Request class (e.g., StoreShiftRequest.php)
use Illuminate\Foundation\Http\FormRequest;
use App\Rules\ShiftBelongsToUserRule;
class StoreShiftRequest extends FormRequest
{
public function rules()
{
return [
'shift_id' => [
'required',
'exists:shifts,id', // Basic existence check
new ShiftBelongsToUserRule(), // The ownership check
],
// other rules...
];
}
}
Solution 2: Leveraging Eloquent for Authorization Checks
While custom validation is excellent for input sanitization, remember that the ultimate source of truth should always be in your Eloquent models. When you fetch a model, it's far more efficient to use Eloquent relationships for authorization checks than performing raw SQL queries within every validation step.
For example, when fetching data for display or update purposes, you would first scope the query using the relationship:
$shift = \App\Models\Shift::where('id', $request->input('shift_id'))
->where('user_id', Auth::id()) // The crucial ownership check
->first();
if (!$shift) {
abort(403, 'Unauthorized action.');
}
This pattern ensures that all data access respects the defined relationships, which is a fundamental principle of building secure applications with Laravel. For more advanced authorization needs involving policies and permissions, exploring how Laravel handles authorization can significantly enhance your application's security posture (check out the documentation on Laravel Authorization).
Conclusion
Validating existence alone is insufficient for securing data. By combining simple exists checks with custom validation rules that incorporate Eloquent relationships (like checking user_id), you create a robust, secure, and maintainable system. Always favor relational logic when dealing with ownership and permissions in Laravel development.