简体   繁体   English

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

[英]How do you update one-to-many relationships in Node.js?

I'm working an a Node app that uses mongoose , mongodb , and restify . 我正在使用的节点应用程序mongoosemongodb ,和restify I'd like to find out as to whether it is good practice to have import code from various models when defining the route function. 我想知道在定义路由功能时是否从各种模型导入代码是一种好习惯。 This should be a fairly straightforward question, I just need guidance and I'll be able to code it myself. 这应该是一个相当简单的问题,我只需要指导,我就能自己编写代码。 Thanks for taking the time to read this. 感谢您抽时间阅读。

I know how to define the relationship, but I'm not sure how I should be making the actual relationship. 我知道如何定义这种关系,但我不确定如何建立这种关系。 That is, in other words, when a car is created, what is the best way to add a car to it. 也就是说,换句话说,当汽车被创建时,向汽车添加汽车的最佳方式是什么。

Please note that I am trying to keep this api RESTful. 请注意,我正在努力保持这个api RESTful。

I have two models that I would have to linked based on the following schema, which is stored in db/schema.js : 我有两个模型,我必须根据以下模式进行链接,该模式存储在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' },
  });

Then I build the models in models/... , where I have a different file for each model. 然后我在models/...构建模型,其中每个模型都有不同的文件。 Right now they each only have one line of code but I left them as independent files for when I need to write model methods. 现在他们每个人只有一行代码,但是当我需要编写模型方法时,我将它们留作独立文件。

In models/car.js : models/car.js

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

In models/user.js : models/user.js

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

And finally, I set up the route with the post and put requests in routes/cars.js 最后,我使用post设置路由并在routes/cars.js请求

This isn't all of it, just the necessary to answer my question. 这不是全部,只是回答我的问题所必需的。

  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);
  }

Would it be appropriate to have code such as the pseudocode in place A and place B? 将代码如伪代码放在A位置和B位置是否合适? The issue that comes to my mind is that I need to require the User model in the routes/cars.js file, which makes things less modular. 我想到的问题是我需要在routes / cars.js文件中要求User模型,这样可以减少模块化。 Would it be better do this in models/car.js? 在models / car.js中这样做会更好吗?

I disagree with the assumption that you need a schema at all. 我不同意你需要一个架构的假设。 I believe that 95% of the time people are using Mongoose they really don't need it because the benefits of having the schema defined like that just don't outweigh the disadvantages for what people are doing with it. 我相信人们95%的时间都在使用Mongoose他们真的不需要它,因为定义这样的模式的好处不会超过人们用它做什么的缺点。 If there is some critical and unusual role that verifying that data objects match a schema has in your application then maybe that is different. 如果在应用程序中验证数据对象与模式匹配时存在一些关键且不寻常的角色,那么可能会有所不同。 But you have to do that on the front end anyway and I just don't think that most systems really need to duplicate that effort in a different way on the back end. 但是你必须在前端做到这一点我并不认为大多数系统真的需要在后端以不同的方式复制这种努力。

For the vast majority of cases, databases are relatively small and simple. 对于绝大多数情况,数据库相对较小且简单。 Your case probably isn't an exception. 您的情况可能不是例外。 So let's actually take advantage of the fact that we have a schemaless database and lose the boilerplate. 因此,让我们实际利用我们拥有无模式数据库并丢失样板的事实。

It looks like you are planning on writing a ton of boilerplate code for every collection. 您似乎计划为每个集合编写大量的样板代码。 Don't do that. 不要那样做。 Instead take a look at some CRUD systems for Node like these: https://github.com/AndrewRademacher/auto-crud Does MongoDB have a native REST interface? 相反,请看一下Node的一些CRUD系统: https//github.com/AndrewRademacher/auto-crud MongoDB是否有原生REST接口? and/or you can add on to them for your specific needs. 和/或您可以根据您的特定需求添加它们。

I think some part of this general philosophy about putting that business about adding the cars to the user object for that session on the back end is probably related to security. 我认为这个关于将业务添加到后端会话的用户对象的业务的一般理念的一部分可能与安全性有关。 In other words, the assumption is that you can't just take the front-end's word for it and save a user object with whatever cars it has, because someone might be trying to hack the front-end. 换句话说,假设你不能仅仅拿出前端的话来保存用户对象以及它拥有的任何汽车,因为有人可能试图破解前端。 Again, for the vast majority of cases, I just don't see this as a sensible assumption. 同样,对于绝大多数情况,我只是不认为这是一个明智的假设。

I think it will be much simpler if you just have some generic ways to do CRUD on the back end and just add the cars to the user's data object on the front end. 我认为如果你只有一些通用的方法在后端做CRUD并且只是将汽车添加到前端的用户数据对象,那将会简单得多。 And you can do fine-grained security on the back end on top of a generic CRUD system if you actually need to (ie, there is a valid business justification, like something that affects the bottom line). 如果你真的需要(例如,有一个有效的业务理由,比如影响底线的东西),你可以在通用CRUD系统的顶端做后端的细粒度安全性。

Mainly that stuff is a holdover belief system from when almost all databases were SQL-based and had rigid schemas with static languages on the back-end, so you almost had to use a bunch of boiler-platy code or rely on metaprogramming that was tricky with static languages. 当几乎所有的数据库都是基于SQL的并且在后端有严格的静态语言模式时,主要是东西是一种保留信念系统,所以你几乎不得不使用一堆样锅代码或者依赖于元编程很棘手使用静态语言。

I think that in 95% of cases, now that we have things like JSON and dynamic languages, it is wrong to have a bunch of boilerplate that is just differentiated by entity and sometimes field names. 我认为在95%的情况下,现在我们有JSON和动态语言这样的东西,有一堆样板只是由实体和有时字段名称区分是错误的。

I would make two recommendations: 我会提出两点建议:

  1. Abstract the function code in the routes file to a controller for each of the rest functions if you expect them to grow relatively large. 如果您希望它们增长得相对较大,则将路径文件中的功能代码抽象到每个其余功能的控制器。

  2. Alternately, you could create your own DAO (database access object) wrappers around each of the tables and then treat them like JavaScript objects instead of tables when making calls in a much simpler routes file. 或者,您可以在每个表周围创建自己的DAO(数据库访问对象)包装器,然后在更简单的路由文件中进行调用时将它们视为JavaScript对象而不是表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM