Skip to content
Advertisement

Laravel Validation Array must contain one item where boolean is true

I’m validating question and answers (for test creation). I’d like to ensure that the answers array contains at least one ‘correct’ item. So where answers.*.correct => true.

I currently have the following:

public function rules()
    {
        return [
            'title' => 'required|string|max:255',
            'test_id' => 'required|integer|exists:tests,id',
            'content' => 'required',
            'answers' => 'required|array',
            'answers.*.text' => 'required|string|max:255',
            'answers.*.correct' => 'required|boolean'
        ];
    }

At the moment i can miss out adding a correct answer causing an impossible question.

I’ve checked the documentation and can’t see anything that stands out.

Any help would be appreciated.

EDIT ANSWER

I used this (as the answer mentions): Laravel validate at least one item in a form array

I managed to create a custom rule like so:

    public function passes($attribute, $value)
    {
        foreach ($value as $arrayElement) {
            if ($arrayElement['correct'] == true) {
                return true;
            }
        }

        return false;
    }

Then in my existing rules() section for the request I added in the new rule i created:

'answers' => ['required', 'array', new ArrayAtLeastOneBoolTrue()],

Advertisement

Answer

You are here validating that the array answers has:

  1. A string with max. 255 chars (text)
  2. A boolean (correct)

To check the completeness of this array, the Laravel request is the wrong place to check. Technically it would be possible to create your own validation rule, but makes no sense here. Instead you should iterate this array in your controller and verify the completeness of each answers. Two more ideas, to do it better:

  • Don’t send all answers and if they were answered correctly in one single array. Instead, send the selected answer to your api with a single request per answer at the moment the user clicks it. This will 1. prevent that somebody can send you the information that he answered 100% correct (not good if this is a school software 🙂 ) and 2. depending on how much questions there are it will reduce the data sent to the server to a minumum, mainly because…
  • … it seems you send the whole text of the question to the server to identify the answer. Use a unique ID per question and send it as question ID + the selected or entered answer.

EDIT: Thanks for the comments, sorry for my misunderstanding here. As mentioned above then of course custom validation makes totally sense here to check per question if at least one answer is correct. Check this out: https://stackoverflow.com/a/53791208/2264877

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement