访问mongoose父文档以获取子文档

时间:2018-06-12 20:44:20

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

我有一个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字段,可以为该用户指定默认单位。如果该用户在未指定单位的情况下发布了weighIn,则该weighIn应使用用户的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不起作用,因为我不想覆盖所有用户的WeighIns单位,只是在POST请求中未指定时。

我是不是在我的控制器中执行此操作?我从Rails开始,所以我的大脑上刻有“胖模型,瘦小的控制器”。

1 个答案:

答案 0 :(得分:0)

您可以使用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传递给它即可。 这样,您将获得“胖模型,瘦控制器”。