【问题标题】:Access mongoose parent document for default values in subdocument访问 mongoose 父文档以获取子文档中的默认值
【发布时间】:2018-11-22 08:20:10
【问题描述】:

我有一个用于 Express/Mongo 健康跟踪应用的后端 API。

每个用户都有一个weighIns 数组,子文档包含一个值、一个单位和记录的日期。如果未指定单位,则单位默认为 'lb'

const WeighInSchema = new Schema({
  weight: {
    type: Number,
    required: 'A value is required',
  },
  unit: {
    type: String,
    default: 'lb',
  },
  date: {
    type: Date,
    default: Date.now,
  },
});

每个用户还有一个 defaultUnit 字段,可以为该用户指定一个默认单位。如果该用户在未指定单位的情况下发布了 weightIn,则该 weightIn 应使用用户的 defaultUnit(如果存在),否则默认为 'lb'

const UserSchema = new Schema({
  email: {
    type: String,
    unique: true,
    lowercase: true,
    required: 'Email address is required',
    validate: [validateEmail, 'Please enter a valid email'],
  },
  password: {
    type: String,
  },
  weighIns: [WeighInSchema],
  defaultUnit: String,
});

这个逻辑的正确位置在哪里?

我可以在我的 WeighInsController 的 create 方法中轻松地做到这一点,但这似乎充其量不是最佳实践,最坏的情况是反模式。

// WeighInsController.js

export const create = function create(req, res, next) {
  const { user, body: { weight } } = req;
  const unit = req.body.unit || user.defaultUnit;
  const count = user.weighIns.push({
    weight,
    unit,
  });
  user.save((err) => {
    if (err) { return next(err); }
    res.json({ weighIn: user.weighIns[count - 1] });
  });
};

似乎不可能在 Mongoose 模式中指定对父文档的引用,但我认为更好的选择是在子文档的 pre('validate') 中间件中。我也看不到在子文档中间件中引用父文档的方法。

注意:This answer 不起作用,因为我不想在 POST 请求中未指定时覆盖所有用户的 WeighIns 单位。

我是否被困在我的控制器中?我从 Rails 开始,所以我的大脑上刻着“胖模型,瘦控制器”。

【问题讨论】:

    标签: mongodb express mongoose mongoose-schema mongoose-middleware


    【解决方案1】:

    您可以使用this.parent() 函数从子文档 (WeighIn) 访问父 (用户)。

    但是,我不确定是否可以将静态添加到子文档中,这样就可以实现:

    user.weighIns.myCustomMethod(req.body)
    

    相反,您可以在 UserSchema 上创建一个方法,例如 addWeightIn:

    UserSchema.methods.addWeightIn = function ({ weight, unit }) {
      this.weightIns.push({
        weight,
        unit: unit || this.defaultUnit
      })
    }
    

    然后只需在您的控制器中调用user.addWeightIn 函数并将req.body 传递给它。 这样,您将获得“胖模型,瘦控制器”。

    【讨论】:

      猜你喜欢
      • 2017-02-28
      • 2016-05-31
      • 2013-03-19
      • 1970-01-01
      • 2015-09-14
      • 2016-08-10
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多