【问题标题】:Make all fields required in Mongoose在 Mongoose 中填写所有必填字段
【发布时间】:2013-11-14 18:13:21
【问题描述】:

Mongoose 似乎默认使所有字段都不需要。有没有办法在不更改每个字段的情况下使所有字段成为必需的:

Dimension = mongoose.Schema(
  name: String
  value: String
)

Dimension = mongoose.Schema(
  name:
    type: String
    required: true
  value: 
    type: String
    required: true
)

因为我有很多,它会变得非常难看。

【问题讨论】:

  • 如果所有字段都需要,为什么要使用无模式数据库?
  • 无模式数据库与必填字段无关,您可以在关系数据库中使用非必填字段,反之亦然。 (在我看来)
  • 我觉得这应该是api的一部分。也就是说,在构建 Schema 时将 this 作为选项传递给构造函数。奇怪的是它不存在,并且提供聚合它们的解决方案非常难看。可能最干净的方法是用装饰器包装 mongoose.Schema 并自己构建这个构造函数。

标签: node.js mongodb mongoose schema


【解决方案1】:

你可以这样做:

var schema = {
  name: { type: String},
  value: { type: String}
};

var requiredAttrs = ['name', 'value'];

for (attr in requiredAttrs) { schema[attr].required = true; }

var Dimension = mongoose.schema(schema);

或者对于所有属性(使用下划线,这很棒):

var schema = {
  name: { type: String},
  value: { type: String}
};

_.each(_.keys(schema), function (attr) { schema[attr].required = true; });

var Dimension = mongoose.schema(schema);

【讨论】:

  • 而隐式声明所需属性只会把问题抛到一边,让它变得更加丑陋。
【解决方案2】:

我最终这样做了:

r_string = 
  type: String
  required: true 

r_number = 
  type: Number
  required: true

对于其他数据类型。

【讨论】:

  • 你最后把这个放在哪里了? @maxko87
【解决方案3】:

所有字段属性都在schema.paths[attribute]schema.path(attribute)

一种正确的方法:定义何时不需要字段,

Schema = mongoose.Schema;
var Myschema = new Schema({
    name : { type:String },
    type : { type:String, required:false }
})

并默认将它们全部设为必需:

function AllFieldsRequiredByDefautlt(schema) {
    for (var i in schema.paths) {
        var attribute = schema.paths[i]
        if (attribute.isRequired == undefined) {
            attribute.required(true);
        }
    }
}

AllFieldsRequiredByDefautlt(Myschema)

下划线方式:

_=require('underscore')
_.each(_.keys(schema.paths), function (attr) {
    if (schema.path(attr).isRequired == undefined) {
        schema.path(attr).required(true);
    }
})

测试一下:

MyTable = mongoose.model('Myschema', Myschema);
t = new MyTable()
t.save()

【讨论】:

    【解决方案4】:

    你可以编写一个 mongoose 模式插件函数来遍历模式对象并对其进行调整以使每个字段都成为必需的。然后每个模式只需要 1 行:Dimension.plugin(allRequired)

    【讨论】:

      【解决方案5】:

      Mongoose 没有提供设置所有字段的方法,但是可以递归来做。

      就像 Peter 提到的那样,您可以将其插件化以重用代码。

      递归设置:

      // game.model.js
      var fields = require('./fields');
      var Game = new Schema({ ... });
      
      for(var p in Game.paths){
        Game.path(p).required(true);
      }
      

      插件化:

      // fields.js
      module.exports = function (schema, options) {
        if (options && options.required) {
          for(var p in schema.paths){
            schema.path(p).required(true);
          }
        }
      }
      
      // game.model.js
      var fields = require('./fields');
      var Game = new Schema({ ... });
      Game.plugin(fields, { required: true });
      

      【讨论】:

        【解决方案6】:

        我不确定在 Mongoose 中是否有更简单的方法,但我会在您的 IDE/编辑器中执行以下操作:

        像往常一样列出你的字段:

        Dimension = mongoose.Schema(
          name: String
          value: String
        )
        

        然后在 String 上进行查找和替换,并将其替换为 {type: String, required: true}, 给你:

        Dimension = mongoose.Schema(
          name: {type: String, required: true},
          value:  {type: String, required: true},
        )
        

        然后对Number 和其他类型执行相同操作。

        【讨论】:

          【解决方案7】:

          在前面的答案的基础上,下面的模块将默认设置必填字段。前面的答案没有递归嵌套对象/数组。

          用法:

          const rSchema = require("rschema");
          
          var mySchema = new rSchema({
              request:{
                  key:String,
                  value:String
              },
              responses:[{
                  key:String,
                  value:String
              }]
          });
          

          节点模块:

          const Schema = require("mongoose").Schema;
          
          //Extends Mongoose Schema to require all fields by default
          module.exports = function(data){
              //Recursive
              var makeRequired = function(schema){
                  for (var i in schema.paths) {
                      var attribute = schema.paths[i];
                      if (attribute.isRequired == undefined) {
                          attribute.required(true);
                      }
                      if (attribute.schema){
                          makeRequired(attribute.schema);
                      }
                  }
              };
          
              var schema = new Schema(data);
              makeRequired(schema);
              return schema;
          };
          

          【讨论】:

            猜你喜欢
            • 2020-04-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-19
            • 2017-03-28
            • 2019-11-26
            • 1970-01-01
            相关资源
            最近更新 更多