你如何更新Node.js中的一对多关系?

时间:2013-07-15 05:08:09

标签: node.js mongodb rest mongoose restify

我正在使用一个使用mongoosemongodbrestify的节点应用。我想知道在定义路由功能时是否从各种模型导入代码是一种好习惯。这应该是一个相当简单的问题,我只需要指导,我就能自己编写代码。感谢您抽时间阅读。

我知道如何定义关系,但我不确定如何建立实际关系。也就是说,换句话说,当汽车被创建时,向汽车添加汽车的最佳方式是什么。

请注意,我正在努力保持这个api RESTful。

我有两个模型,我必须根据以下模式进行链接,该模式存储在db/schema.js中:

//schema.js
  var restify = require('restify');
  var mongoose = require('mongoose');
  var Schema = mongoose.Schema;
  var ObjectId = Schema.ObjectId;

// User Schema

  exports.User = new Schema({
    id: ObjectId,
    name: String,
    cars: [{ type: ObjectId, ref: 'Car' }],
  });

// Car Schema

  exports.Car = new Schema({
    id: ObjectId,
    name: String,
    _user: { type: ObjectId, ref: 'User' },
  });

然后我在models/...中构建模型,其中每个模型都有不同的文件。现在他们每个人只有一行代码,但是当我需要编写模型方法时,我将它们留作独立文件。

models/car.js

  mongoose.model('Car', db_schema.Car);

models/user.js

  mongoose.model('User', db_schema.User);

最后,我使用帖子设置路线,并在routes/cars.js

中提出请求

这不是全部,只是回答我的问题所必需的。

  module.exports = function(app) {

    function putCar(req, res, next) {
      Car.findById(req.params.id, function (err, car) {
        if (!err) {
          car.name = req.params.name;
          car.save(function (err) {
            if (!err) {
             // PLACE A
             // current_user = get current user from session
             // current_user.cars.push(car);
              res.send(car);
              return next();
            } else {
              return next(new restify.InternalError(err));
            }
          });
        } else {
          return next(new restify.MissingParameterError('ObjectId   required.'));
        }
      });
     }

    function postCar(req, res, next) {
      var car = new Car(req.params);
      car.save(function (err, car) {
        if (!err) {
          // PLACE B
          // current_user = get current user from session
          // current_user.cars.push(car);
          res.send(car);
        } else {
          return next(err);
        }
      });
    }

    app.post('api/car', postCar);
    app.put('/api/car', putCar);
  }

将代码例如伪代码放在A和B中是否合适?我想到的问题是我需要在routes / cars.js文件中要求User模型,这样可以减少模块化。在models / car.js中这样做会更好吗?

2 个答案:

答案 0 :(得分:4)

我不同意你需要一个架构的假设。我相信人们95%的时间都在使用Mongoose他们真的不需要它,因为定义这样的模式的好处不会超过人们用它做什么的缺点。如果在应用程序中验证数据对象与模式匹配时存在一些关键且不寻常的角色,那么可能会有所不同。但是你必须在前端做到这一点,我只是不认为大多数系统真的需要在后端以不同的方式复制这种努力。

对于绝大多数情况,数据库相对较小且简单。您的情况可能不是例外。因此,让我们实际利用我们拥有无模式数据库并丢失样板的事实。

您似乎计划为每个集合编写大量的样板代码。不要那样做。相反,请查看一些节点的CRUD系统:https://github.com/AndrewRademacher/auto-crud Does MongoDB have a native REST interface?和/或您可以根据自己的特定需求添加它们。

我认为这个关于将业务添加到后端会话的用户对象的业务的一般理念的一部分可能与安全性有关。换句话说,假设你不能仅仅拿出前端的话来保存用户对象以及它拥有的任何汽车,因为有人可能试图破解前端。同样,对于绝大多数情况,我只是不认为这是一个明智的假设。

我认为如果你只有一些通用的方法在后端做CRUD并且只是将汽车添加到前端的用户数据对象,那将会简单得多。你可以在一个通用的CRUD系统的顶部在后端做细粒度的安全性,如果你真的需要(即存在一个有效的商业理由,喜欢的事,影响了底线)。

主要的东西就是从当时几乎所有的数据库都是基于SQL的,并与静态语言的后端刚性架构缓缴信念系统,让你几乎不得不用一堆锅炉片状代码或依赖于元编程这对于静态语言来说很棘手。

我认为在95%的情况下,现在我们已经拥有了JSON和动态语言之类的东西,但是有一堆样板只是由实体和有时字段名称来区分是错误的。

答案 1 :(得分:0)

我会提出两条建议:

  1. 如果您希望它们相对较大,请将路径文件中的功能代码提取给控制器,以用于其他每个功能。

  2. 或者,您可以在每个表周围创建自己的DAO(数据库访问对象)包装器,然后在更简单的路由文件中调用时将它们视为JavaScript对象而不是表。

    < / LI>