Laravel验证数组 - 有时如果数组中存在另一个字段,则忽略字段

时间:2017-02-27 17:19:22

标签: php laravel validation

我正在为Laravel应用程序编写一些验证规则,如果存在另一个字段,我需要忽略一些字段。我知道“有时”功能可能是最好的方法,但如何用数组实现功能呢?

第一次尝试(无法正常工作,因为只要字段存在,Laravel就会验证):

// Device Rules
$deviceRules = [
    'devices' => 'required|array|min:1',
    'devices.*.id' => 'integer',
    'devices.*.network' => 'max:255',

    'devices.*.code' => "required_without:devices.*.id|max:255|unique:devices,code",
    'devices.*.make_id' => 'required_without:devices.*.id|in:' . Make::getImplodedKeys(),
    'devices.*.model_id' => 'required_without:devices.*.id|in:' . DeviceModel::getImplodedKeys(),

    'devices.*.fault_id' => 'required|array|min:1',
    'devices.*.fault_id.*' => 'in:' . Fault::getImplodedKeys(),
    'devices.*.warranty' => 'required|boolean'
]

所以我的第二次尝试使用'有时()'(但我不太清楚如何实现它。):

public function rules()
{
    // Device Rules
    $deviceRules = [
        'devices' => 'required|array|min:1',
        'devices.*.id' => 'integer',
        'devices.*.network' => 'max:255',

        'devices.*.fault_id' => 'required|array|min:1',
        'devices.*.fault_id.*' => 'in:' . Fault::getImplodedKeys(),
        'devices.*.warranty' => 'required|boolean'
    ];

    return $deviceRules ;
}

protected function getValidatorInstance(){
    $validator = parent::getValidatorInstance();

    $validator->sometimes('devices.*.code', 'required|max:255|unique:devices,code', function($input)
    {
        return isset($input->devices.*.id);
    });

    $validator->sometimes('devices.*.make_id', 'required|in:' . Make::getImplodedKeys(), function($input)
    {
        return isset($input->devices.*.id);
    });

    $validator->sometimes('devices.*.model_id', 'required|in:' . DeviceModel::getImplodedKeys(), function($input)
    {
        return isset($input->devices.*.id);
    });

    return $validator;
}

我没有对此进行过测试,因为显然它不起作用,return isset($input->devices.*.id);毫无疑问会抛出错误。我该如何正确实现这个?

1 个答案:

答案 0 :(得分:2)

我找到了自己的解决方案

见下文:

// Device Rules
$deviceRules = [
    'devices' => 'required|array|min:1',
    'devices.*.id' => 'integer',
    'devices.*.network' => 'max:255'
];

foreach($this['devices'] as $index => $device){
    if(!isset($device['id'])){

        $additionalDeviceRules = [
            'devices.' .$index. '.code' => 'required|max:255|unique:devices,code',
            'devices.' .$index. '.make_id' => 'required|in:' . Make::getImplodedKeys(),
            'devices.' .$index. '.model_id' => 'required|in:' . DeviceModel::getImplodedKeys(),

            'devices.' .$index. '.fault_id' => 'required|array|min:1',
            'devices.' .$index. '.fault_id.*' => 'in:' . Fault::getImplodedKeys(),
            'devices.' .$index. '.warranty' => 'required|boolean'
        ];

        $deviceRules = array_merge($deviceRules, $additionalDeviceRules);
    }
}

基本上,您需要指定索引ID,而不是使用占位符索引*。然后,Laravel可以解析索引ID并有条件地应用您的规则。