确保对象与数据模型匹配

时间:2019-04-12 16:00:30

标签: javascript data-structures

想象一下,我有一个像这样的数据模型:

// Pseudo-code, as I don't know how to achieve this
const Model = {
    name: String.required,
    description: String.optional,
    rank: Number.required,
    // ...
}

基本上,这意味着对象必须具有属性name,并且必须是String 。属性description可选的,但是必须定义为String。等等

现在,假设我有一堆对象:

const obj1 = {
    name: 'Object 1',
    rank: 1,
}
const obj2 = {
    description: 'This is object 2',
    rank: 2,
}

为了将我的对象保存在NoSQL数据库(Firebase的Firestore)中,我想确保每个Object 匹配 Model。这样可以防止缺少字段。

在我的示例中,obj1应该通过,但是obj2应该没有name属性。

有没有办法抛出错误消息,其中缺少哪些属性?

1 个答案:

答案 0 :(得分:0)

解决方案:

您可以创建一个简单函数,该函数将基于一组必需和可选参数来验证您的模型。

注意:以下内容在函数中硬编码了requiredoptional参数,但是您也可以毫不费力地传递它们并更改代码。只需删除声明并将它们作为参数添加到函数中即可。


代码

function validateModel(obj) {
  let
    // parameters specification
    required = ["name", "rank"],
    optional = ["description"],

    // helper methods
    toObjects = (a, v) => Reflect.has(obj, v) ? (a[v] = obj[v], a) : a,
    grab = (type) => type.reduce(toObjects, {}),
    payload = () => Object.assign(grab(required), grab(optional)),
    notValid = v => !Reflect.has(obj, v);

  //output
  if (required.some(notValid)) return false;
  return payload();
}

工作示例:

//setup
let log = (x) => { return console.log(x), log };
const Model={name:"n",description:"d",rank:"r"},Model2={rank:"a"},Model3={rank:"b",name:"b"};

// Validation Method:
function validateModel(obj) {
  let
    // parameters specification
    required = ["name", "rank"],
    optional = ["description"],

    // helper methods
    toObjects = (a, v) => Reflect.has(obj, v) ? (a[v] = obj[v], a) : a,
    grab = (type) => type.reduce(toObjects, {}),
    payload = () => Object.assign(grab(required), grab(optional)),
    notValid = v => !Reflect.has(obj, v);

  //output
  if (required.some(notValid)) return false;
  return payload();
}


// Examples:
log
  (validateModel(Model) || "Invalid Model")
  (validateModel(Model2) || "Invalid Model")
  (validateModel(Model3) || "Invalid Model")


使其具有多种用途:

如果创建类似模型检查器的工具,最好是能够使用它检查多种类型的模型。下面的代码创建一个构造函数,该构造函数采用充满结构的Object。每个结构都包含requiredoptional参数的数组。

ModelChecker构造函数使用单个方法validate返回一个对象。通过传入要检查的对象和要检查的模型结构的名称,可以确定模型是否有效。


工作示例:

//setup
let log = (x) => { return console.log(x), log };
const Model={name:"n",description:"d",rank:"r"},Model2={rank:"a"},Model3={rank:"b",name:"b"}, Car={"color":"black", "name": "toyota" }, Car2={"name":"chevy"};

//setup validation structures
const structs = {
  "identity": {
    required: ["name", "rank"],
    optional: ["description"]
  },
  "car": {
    required: ["color"],
    optional: ["name"]
  }
}

// model checker constructor
function ModelChecker(structs) {
  let proto = {
    structs
  };
  
  proto.validate = function validateModel(obj, struct) {
    if (!this.structs[struct]) return false;

    let
      // parameters specification
      required = this.structs[struct].required,
      optional = this.structs[struct].optional,

      // helper methods
      toObjects = (a, v) => Reflect.has(obj, v) ? (a[v] = obj[v], a) : a,
      grab = (type) => type.reduce(toObjects, {}),
      payload = () => Object.assign(grab(required), grab(optional)),
      notValid = v => !Reflect.has(obj, v);

    //output
    if (required.some(notValid)) return false;
    return payload();
  }

  return proto;
}

// Examples:

let mc = ModelChecker(structs);
log
  (mc.validate(Model, "identity") || "Invalid Model")
  (mc.validate(Model2, "identity") || "Invalid Model")
  (mc.validate(Model3, "identity") || "Invalid Model")
  (mc.validate(Car, "car") || "Invalid Model")
  (mc.validate(Car2, "car") || "Invalid Model")