输入验证独占或

时间:2014-10-24 12:01:03

标签: php laravel laravel-4 laravel-validation

我有一个名为Answer的模型。

这个模型有两种可能的关系。 QuestionProduct。 但是,答案应该只有一个关系。问题或产品。

有一个表单可以创建答案。

此表单有三个输入。其中两个是<select>输入。另一个是文本输入,名为name。

我希望我的验证只允许填写一份。

我目前的验证:

$validator = Validator::make(
    Input::all(),
    array('name' => array('required'))
);

$validator->sometimes('product', array('required', 'numeric'), function ($input) {
    return !is_numeric($input->question);
});

$validator->sometimes('question', array('required', 'numeric'), function ($input) {
    return !is_numeric($input->product);
});

要求至少填写一个,但也允许两个。

所以,我的问题是:如何将我的验证更改为仅允许填写其中一个选项。 但其中一个必须一直填写。

选择1:

<select name="question" class="form-control">
    <option>None</option>
    <option value="1" selected="selected">Question 1</option>
    <option value="2">Question 2</option>
</select>

选择2:

<select name="product" class="form-control">
    <option>None</option>
    <option value="2" selected="selected">Product 1</option>
    <option value="3">Product 2</option>
</select>

3 个答案:

答案 0 :(得分:4)

首先关闭。您必须在&#34;无&#34;中指定空值。选项:

<option value=''>None</option>

您正在寻找XOR运营商,在这种情况下您需要创建自定义验证规则:

Validator::extendImplicit('xor', function($attribute, $value, $parameters)
{
    if( $value XOR app('request')->get($parameters[0]))
        return true;
    return false;
});
Validator::replacer('xor', function($message, $attribute, $rule, $parameters)
{
    // add indefinite articles
    $IAattribute = (stristr('aeiou', $attribute[0]) ? 'an ' : 'a ') . $attribute;
    $parameters[0] = (stristr('aeiou', $parameters[0][0]) ? 'an ' : 'a ') . $parameters[0];

    if(app('request')->get($attribute))
        return 'You cannot choose both '.$IAattribute.' and '.$parameters[0].'.';
    return $IAattribute.' or '.$parameters[0].' is required.';
});


$validator = Validator::make(
    app('request')->all(),
    array('name' => array('required')
    ,'product' => array('xor:question')
));

答案 1 :(得分:4)

@ Razor的自定义XOR验证规则相当不错,但如果您不想创建自定义规则,还有另一条路线。您可以使用Input向表示约束的Input::merge添加值,然后使用这些值进行验证:

Input::merge(array(
    'hasBoth'    => Input::has('product')  && Input::has('question'),
    'hasNeither' => !Input::has('product') && !Input::has('question')
));

$validator = Validator::make(
    Input::all(), array(
        'name'       => 'required',
        'hasNeither' => 'size:0',
        'hasBoth'    => 'size:0',
    ), array(
        'hasNeither.size' => 'A question or a product is required.',
        'hasBoth.size'    => 'You cannot choose both a question and a product.'         
    )
);

您仍应将表单中的空值更改为<option value=''>None</option>

与使用XOR比较不同,此方法允许您为无值两个值返回单独的错误消息,而无需进一步检查错误。

答案 2 :(得分:0)

required_without validation rule可能就是您想要的:

  

验证字段必须仅在其他任何字段存在时才存在   指定的字段不存在。

question字段设置为required_without:product,将product字段设置为required_without:question