使用Joi,要求两个字段中的一个非空

Bre*_*dan 12 javascript hapijs joi

如果我有两个字段,我只想验证至少一个字段是非空字符串,但是当两个字段都是空字符串时失败.

这样的事情无法验证

var schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.string()
}).or('a', 'b');
Run Code Online (Sandbox Code Playgroud)

验证时

{a: 'aa', b: ''}
Run Code Online (Sandbox Code Playgroud)

or条件只测试了两种关键的存在ab,但确实为条件测试是否a还是b如此.Joi.string()空字符串会失败.

以下是一些要展示的测试用例的要点

http://requirebin.com/?gist=84c49d8b81025ce68cfb

Kev*_* Wu 17

下面的代码对我有用.我使用了替代品,因为.或者是真的测试密钥的存在,你真正想要的是另一种选择,你可以允许一个密钥或另一个密钥为空.

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']);
}
Run Code Online (Sandbox Code Playgroud)

  • 这确实有效,但不是真正的可扩展性 - 如果你有两套,你需要四种选择,如果你有三套,那么你需要八套.但似乎没有更好的方法. (13认同)

t k*_*t k 6

对我有用的使用 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')
Run Code Online (Sandbox Code Playgroud)

.or('a', 'b')防止aANDb为空(与 '' 相反)。

  • 我刚刚意识到这将返回消息“需要“b””而不是“需要“a”或“b””,但不知道如何解决这个问题。 (2认同)