0

Say I have a custom logic for validating the uniqueness of a FormRequest field, something requiring to find another resource in the database like below:

class CreateMyResourceRequest extends FormRequest {
public function rules() {
        return [
            'my_field' => [
                Rule::unique('some_other_resource', 'some_column')
                    ->where(function ($query) {
                        $otherResource = SomeOtherResource::where(...)->firstOrFail();

                        // Process the retrieved resource
                    }),
            ]

The firstOrFail() call obviously makes the request fail with a 404 - Not found while I would like to return a 422 with a validation error on the field.

Is there a way to achieve this while still using the Rule::unique() provided by the framework?

Thanks in advance!

3
  • Rule::unique() is already sending validation error response, what are you trying to achieve? Commented Feb 19, 2022 at 22:31
  • As I said, I need to load another resource from the database in order to validate the uniqueness of one of the fields of the request. When doing so, I use the firstOrFail() method as I need to know that the referenced resource actually exists.. but that gives back a 404 rather than a validation error.. Commented Feb 19, 2022 at 22:35
  • More generally, is there a way to make a rule fail when passing in a closure as parameter? Commented Feb 19, 2022 at 22:36

2 Answers 2

1

I'd suggest the following

public function rules()
{
    return [
        "your_field" => ["you_can_have_more_validations_here", function($key, $value, $cb) {

            $queryResult = SomeModel::find(1);

            if (someCondition) {
                $cb("your fail message");
            }
        }]
    ];
}

when the $cb run the validation will fail with 422

Sign up to request clarification or add additional context in comments.

2 Comments

I've had a look at the other options but this is it probably, as it gives the most flexibility out of all. Thanks for the answer!
Ah, just for clarity if anyone else gets to read this, the callback doesn't prevent subsequent statements from executing, so if one has to break the validation logic at a certain point a return is needed
0

Don't use firstOrFail, instead just use first and check if the output is null. If it is, return false.

Alternatively, the more Laravel way of doing it is:

$query->leftJoin('otherresource', 'primarykey', 'foreignkey')->where(...)

1 Comment

I'm trying to return false at the beginning of the closure passed as parameter to the where() method and I'm expecting it to fail straight away.. but it doesn't. Are you referring to the case when the rule is actually a closure rather than the one where a closure is passed to a rule?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.