charles-wc's avatar

Creating Custom Validator for multiple fields

I am wondering how I can create a Rule that will take in multiple form fields, then make a query to see if a record exists with those values. For example, if I have the fields:

type
start_date
length
user_id

I'd like to create a rule that creates a query that is like so:

->where("type", $type)
->whereBetween("start_date", [
		$start_date,
		$start_date + $length
])
->where('user_id', $user_id) // this would actually be in a pivot table
->where('id', '!=', $id) // and this is only present if we are updating the record, not saving

Would this be best done as a Rule, or some other way?

0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

You can absolutely create a custom validation rule for this scenario using Laravel’s custom Rule objects. The key is that when you need to validate based on multiple fields, you should pass those fields into your Rule, or use the Validator::extend approach for even more flexibility.

Approach: Custom Rule Object

  1. Create the Rule:

Run:

php artisan make:rule UniqueBooking
  1. Implement the Rule:

In app/Rules/UniqueBooking.php:

  1. Use the Rule in Your Form Request or Validator:
use App\Rules\UniqueBooking;

public function rules()
{
    return [
        'type' => ['required'],
        'start_date' => ['required', 'date'],
        'length' => ['required', 'integer'],
        'user_id' => ['required', 'exists:users,id'],
        'id' => ['sometimes'], // for updates

        // Apply the custom rule to any field, or use 'start_date' as the trigger
        'start_date' => [
            'required',
            'date',
            new UniqueBooking(
                $this->input('start_date'),
                $this->input('length'),
                $this->input('user_id'),
                $this->input('id') // pass null if creating
            ),
        ],
    ];
}

Notes:

  • Adjust "pivot_table" to your actual table name.
  • Adjust the date calculation as needed for your use case.
  • You can trigger the rule on any field, but start_date is a common choice.

Summary:
This is best done as a custom Rule, and you can pass all necessary fields into the Rule’s constructor for multi-field validation. This keeps your validation logic clean and reusable.

Please or to participate in this conversation.