One solution would be to create a custom validation rule that extends the Laravel's exists rule and returns the existing model instance instead of a boolean value. Here's an example:
- Create a new custom validation rule by running the following command in your terminal:
php artisan make:rule ExistingEvent
- Open the
ExistingEventclass that was just created in theapp/Rulesdirectory and modify it as follows:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use App\Models\Event;
class ExistingEvent implements Rule
{
protected $event;
public function passes($attribute, $value)
{
$this->event = Event::where('slug', $value)->first();
return $this->event !== null;
}
public function message()
{
return 'The selected event does not exist.';
}
public function getEvent()
{
return $this->event;
}
}
- Modify your FormRequest validation rule to use the new
ExistingEventrule:
use App\Rules\ExistingEvent;
...
public function rules()
{
return [
'event' => ['required', 'string', 'max:255', new ExistingEvent],
];
}
- In your controller method, you can access the existing
Eventmodel instance by calling thegetEventmethod on theExistingEventinstance:
use App\Rules\ExistingEvent;
...
public function store(Request $request)
{
$validatedData = $request->validate([
'event' => ['required', 'string', 'max:255', new ExistingEvent],
]);
$event = (new ExistingEvent)->getEvent();
// Do something with the $event model instance...
}
This way, you avoid running an unnecessary query to retrieve the Event model instance in your controller method.