使用 Joi,要求两个字段之一不为空
Posted
技术标签:
【中文标题】使用 Joi,要求两个字段之一不为空【英文标题】:Using Joi, require one of two fields to be non empty 【发布时间】:2015-05-06 01:15:49 【问题描述】:如果我有两个字段,我只想验证至少一个字段何时为非空字符串,但当两个字段均为空字符串时验证失败。
类似这样的东西无法验证
var schema = Joi.object().keys(
a: Joi.string(),
b: Joi.string()
).or('a', 'b');
验证时
a: 'aa', b: ''
or
条件仅测试是否存在键 a
或 b
,但会测试 a
或 b
的条件是否为真。 Joi.string()
将因空字符串而失败。
这里有一些测试用例来演示的要点
http://requirebin.com/?gist=84c49d8b81025ce68cfb
【问题讨论】:
【参考方案1】:下面的代码对我有用。我使用了替代方案,因为 .or 确实在测试密钥的存在,而您真正想要的是允许一个或另一个为空的替代方案。
var console = require("consoleit");
var Joi = require('joi');
var schema = Joi.alternatives().try(
Joi.object().keys(
a: Joi.string().allow(''),
b: Joi.string()
),
Joi.object().keys(
a: Joi.string(),
b: Joi.string().allow('')
)
);
var tests = [
// both empty - should fail
a: '', b: '',
// one not empty - should pass but is FAILING
a: 'aa', b: '',
// both not empty - should pass
a: 'aa', b: 'bb',
// one not empty, other key missing - should pass
a: 'aa'
];
for(var i = 0; i < tests.length; i++)
console.log(i, Joi.validate(tests[i], schema)['error']);
【讨论】:
这确实有效,但不是真正可扩展的——如果你有两组,你需要四个替代方案,如果你有三组,那么你需要八个。不过似乎没有更好的方法。 太棒了。谢谢【参考方案2】:另一种使用 Joi.when() 的方法对我有用:
var schema = Joi.object().keys(
a: Joi.string().allow(''),
b: Joi.when('a', is: '', then: Joi.string(), otherwise: Joi.string().allow('') )
).or('a', 'b')
.or('a', 'b')
防止 a
AND b
为空(而不是 '')。
【讨论】:
我刚刚意识到这将返回消息"b" is required
而不是 either "a" or "b" is required
但不知道如何解决。【参考方案3】:
如果您想表达两个字段之间的依赖关系,而不必重复对象的所有其他部分,您可以使用when:
var schema = Joi.object().keys(
a: Joi.string().allow(''),
b: Joi.string().allow('').when('a', is: '', then: Joi.string() )
).or('a', 'b');
【讨论】:
【参考方案4】:我遇到https://***.com/a/61212051/15265372 答案的问题是,如果两个字段都给出,你不会遇到任何错误,如果你想解决这个问题,你需要用xor
替换or
。
【讨论】:
以上是关于使用 Joi,要求两个字段之一不为空的主要内容,如果未能解决你的问题,请参考以下文章