Таким образом, Laravel не удаляет вложенные элементы при проверке массива. Для меня это проблема, потому что я пытаюсь динамически обновлять отношения. Если пользователь подделывает другой элемент, Laravel взрывается и выдает мне ошибку:
SQLSTATE[HY000]: General error: 1 no such column: country
Я проверил, в чем проблема, и она оказалась:
$request->validated()
Если вы хотите проверить это, вот мой метод тестирования:
/** @test */
public function test() {
$result = $this->json('GET', route('test'), [
'test' => ['a' => 'test a', 'b' => 'I should not be here'],
'isIgnored' => 'no one is seeing that']
)->json());
}
В контроллере вы подтверждаете:
public function update()
{
$validatedData = request()->validate([
'test.a' => 'required'
]);
}
Результат $ validatedData:
array:1 [
"test" => array:2 [
"a" => "test a"
"b" => "I should not be here"
]
]
Возможно, вы видите, что isIgnored был проигнорирован, а test.b - нет. После этого мой контроллер пытается обновить модель с помощью
$user->$relation()->update($values);
и взрывается. И я подумал об использовании protected $ fillable, но все равно безуспешно. Он просто не игнорирует это.
Я использую sqlite для тестирования на Laravel 5.6.






Если вы проверите исходный код ValidatesRequests на Laravel, вы увидите следующий код:
/**
* Validate the given request with the given rules.
*
* @param \Illuminate\Http\Request $request
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return array
*/
public function validate(Request $request, array $rules,
array $messages = [], array $customAttributes = [])
{
$this->getValidationFactory()
->make($request->all(), $rules, $messages, $customAttributes)
->validate();
return $this->extractInputFromRules($request, $rules);
}
/**
* Get the request input based on the given validation rules.
*
* @param \Illuminate\Http\Request $request
* @param array $rules
* @return array
*/
protected function extractInputFromRules(Request $request, array $rules)
{
return $request->only(collect($rules)->keys()->map(function ($rule) {
return Str::contains($rule, '.') ? explode('.', $rule)[0] : $rule;
})->unique()->toArray());
}
То, что вы видите, вызвано этой строкой в методе map():
return Str::contains($rule, '.') ? explode('.', $rule)[0] : $rule;
Когда ключ содержит ., будет использоваться только первый элемент этой разнесенной строки. Так что в вашем случае он вернет все данные под ключом test.
Этот метод не позволяет отфильтровать определенные элементы массива, вам придется сделать это самостоятельно. Вы уже знаете, что хотите проверить, в вашем случае a, поэтому удалить ненужные данные будет несложно.
Какое содержимое $values в вашем примере?
Я боялся этого ответа ... потому что в моем случае у меня около 10 вложенных элементов и около 6 массивов ... (около 40 элементов, которые мне нужно проверить).