【问题标题】:Add conditional Joi schema添加条件 Joi 架构
【发布时间】:2018-06-09 23:14:03
【问题描述】:

好吧,我放弃了……

如何使selectorSettings 仅在selectorStrategy 设置为tournament 时出现?

selectorStrategy: joi.string().valid(['tournament',  'roulette']).default('tournament'),
selectorSettings: joi.any().when('selectorStrategy', { 
  is: 'tournament',
  then: joi.object().keys({
     tournamentSize: joi.number().integer().default(2),
     baseWeight: joi.number().integer().default(1)
   })
 })

我在选项中设置了stripUnknown: true。我的期望是,如果我通过了:

 selectorStrategy: 'roulette',
 selectorSettings: { tournamentSize: 3 }

我会得到:

selectorStrategy: 'roulette'

如果我这样做:

selectorStrategy: 'tournament'

我会得到:

 selectorStrategy: 'tournament',
 selectorSettings: { tournamentSize: 2, baseWeight: 1 }

【问题讨论】:

  • 很确定你不能那样做。您需要在代码中执行 if 语句,如果符合您的条件则添加子方案

标签: node.js joi


【解决方案1】:

您需要设置一个selectorSettings 默认值,并根据selectorStrategy 的值有条件地将其删除。

让我们来看看你的两个用例。

根据兄弟值删除键

const thing = {
  selectorStrategy: 'roulette',
  selectorSettings: { tournamentSize: 3 },
};

joi.validate(thing, schema, { stripUnknown: true} );

selectorSettings 不会被 stripUnknown 选项删除,因为密钥不是未知的 - 它在您的架构中。

我们需要根据selectorStrategy的值显式剥离它:

.when('selectorStrategy', {
  is: 'tournament',
  otherwise: joi.strip(),
}),

根据兄弟值添加/验证键

const thing = { 
  selectorStrategy: 'tournament'
};

joi.validate(thing, schema);

代码没有为selectorSettings 键本身设置默认值,只为它的属性设置了默认值。由于不需要selectorSettings,因此验证通过。

我们需要设置一个默认值:

selectorSettings: joi
  .object()
  .default({ tournamentSize: 2, baseWeight: 1 })

处理这两种情况的修改后的代码如下所示:

const joi = require('joi');

const schema = {
  selectorStrategy: joi
    .string()
    .valid(['tournament', 'roulette'])
    .default('tournament'),
  selectorSettings: joi
    .object()
    .default({ tournamentSize: 2, baseWeight: 1 })
    .keys({
      tournamentSize: joi
        .number()
        .integer()
        .default(2),
      baseWeight: joi
        .number()
        .integer()
        .default(1),
    })
    .when('selectorStrategy', {
      is: 'tournament',
      otherwise: joi.strip(),
    }),
};

示例

// should remove settings when not a tournament
var thing = {
  selectorStrategy: 'roulette',
  selectorSettings: { tournamentSize: 3 },
};

// returns
{
  "selectorStrategy": "roulette"
}

.

// should insert default settings
var thing = {
  selectorStrategy: 'tournament'
};

// returns
{
  "selectorStrategy": "tournament",
  "selectorSettings": {
    "tournamentSize": 2,
    "baseWeight": 1
  }
}

.

// should add missing baseWeight default
var thing = {
  selectorStrategy: 'tournament',
  selectorSettings: { tournamentSize: 5 } 
};

// returns
{
  "selectorStrategy": "tournament",
  "selectorSettings": {
    "tournamentSize": 5,
    "baseWeight": 1
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多