vlucas/valitron

Is Conditional Validation for a Custom Rule Possible?

Closed this issue · 4 comments

I'm writing a 'unique' rule that is supposed to return true if the value doesn't exist in the db, but I don't want it to run if there's another field error, like a blank value for a required field. At best this will cause a wasted query, at worst, a failed query.

Is this possible using one instance of Valitron? I haven't tried a second instance, but I suppose that could be an option.

Sorry if this has been answered elsewhere, I couldn't find it.

You can do it with a single Valitron instance by checking yourself if you have all the data you need to build the query, something like this:

$validator = new Validator($data);

$validator->rule(function($field, $value, $fields) {
    //make sure we have every field we need before we perform the query
    if (empty($data['username']) || empty($data['password'])){
        //we don't have all the fields we need
        return false;
    }

    //execute query
    return false;
}, 'username')->message("{field} must be unique");

$validator->validate();

For this case however I would use 2 valitron-instances, because it's a easier, and you're essentially performing 2 validations:

  1. Do we have all the data we need in the right format etc. ?
  2. Can we add this data to the database?

Thanks for the help. I don't think the single instance solution mentioned will work because I need to make sure the data is valid, not just that it exists (it may need to be an integer, etc).

It may be simpler to use my own function(s) rather than creating a second Validator instance and custom function(s).

It seems useful to me to have an option of terminating field rule validation upon the first error for each field. That would solve this problem, and speed the processing. Has this been considered? I don't see a case for displaying an array of errors, although I'm sure there are some.

See my comment over at #195 :)

btw solved in what feels like a hacky way by passing the Valitron instanct to the custom rule function as a param then

if (!$params[1]->errors($field)) {
                    return !$params[0]->recordExistsForValue($value);
                }