4

I want to set require validation for array of objects in laravel and used following rule:

[
    'translations.*.languageId' => ['required', 'numeric', Rule::in(Language::all()->pluck('id'))],
    'translations.*.data.title' => 'required|string',
]

but there is problem when i send request without translations key the validate function does not throw require error for translation key.

so i add translations key separately too.

[
    'translations' => ['required', 'array'],
    'translations.*.languageId' => ['required', 'numeric', Rule::in(Language::all()->pluck('id'))],
    'translations.*.data.title' => 'required|string',
]

But there is a problem if an extra key is sent that should not be in the translations array (like locale), it can still be seen in the output of the validate function.

how can i prevent this unexpected result?

2

2 Answers 2

0

As taylorotwell answered my issue and close it there is no way to validator do this filter.

Filter the array to only have the items you actually want after validation.

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

Comments

0

The validated() method returns data for every key that has a validation rule applied to it. Since you have a rule for 'translations', the entire translations array is returned, including any extra keys that you didn't explicitly validate.

To solve this, make your validation rules stricter by telling Laravel exactly which keys are allowed within your arrays.

use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Models\Language; 

$validated = $request->validate([
    'translations'                => ['required', 'array', 'min:1'],
    'translations.*'              => ['required', 'array:languageId,data'],
    'translations.*.languageId'   => ['required', 'numeric', Rule::in(Language::all()->pluck('id'))],

    'translations.*.data'         => ['required', 'array:title'],
    'translations.*.data.title'   => ['required', 'string', 'max:255'],
]);

A Tip:

Your use of Rule::in(Language::all()->pluck('id')) will query the database on every single request. For better performance, it's highly recommended to use the exists rule, which is much more efficient:

Replace this: 'translations.*.languageId' => ['required', 'numeric', Rule::in(Language::all()->pluck('id'))],

With this: 'translations.*.languageId' => ['required', 'numeric', 'exists:languages,id'],

Comments

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.