我正在开发一个使用 mongoose、mongodb 和 restify 的 Node 应用程序。我想知道在定义路由函数时从各种模型导入代码是否是一种好的做法。这应该是一个相当简单的问题,我只需要指导,我就能自己编写代码。感谢您抽时间阅读。
我知道如何定义这种关系,但我不确定我应该如何建立实际关系。也就是说,换句话说,当创建汽车时,向其添加汽车的最佳方式是什么。
请注意,我正在尝试保持此 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 中这样做会更好吗?
最佳答案
我完全不同意您需要模式的假设。我相信 95% 的时间人们在使用 Mongoose 时他们真的不需要它,因为像这样定义模式的好处不会超过人们使用它所做的事情的缺点。如果在您的应用程序中有一些关键和不寻常的角色来验证数据对象是否与模式匹配,那么这可能是不同的。但无论如何你都必须在前端做这件事,我只是认为大多数系统真的不需要在后端以不同的方式重复这项工作。
对于绝大多数情况,数据库相对较小且简单。你的情况可能也不异常(exception)。因此,让我们实际利用我们拥有无模式数据库并丢掉样板这一事实。
您似乎正计划为每个集合编写大量样板代码。不要那样做。相反,看看像这样的 Node 的一些 CRUD 系统:https://github.com/AndrewRademacher/auto-crud Does MongoDB have a native REST interface?和/或您可以根据您的特定需求添加它们。
我认为这种关于在后端为该 session 将汽车添加到用户对象的业务的一般理念的某些部分可能与安全性有关。换句话说,假设您不能只接受前端的话并用它拥有的任何汽车保存用户对象,因为有人可能试图破解前端。同样,对于绝大多数情况,我只是不认为这是一个明智的假设。
我认为如果您只使用一些通用方法在后端执行 CRUD 并在前端将汽车添加到用户的数据对象中,那将会简单得多。如果确实需要,您可以在通用 CRUD 系统之上的后端执行细粒度的安全性(即,有有效的业务理由,比如影响底线的事情)。
主要是,当几乎所有数据库都基于 SQL 并且在后端具有静态语言的严格模式时,这些东西是一个遗留的信念系统,所以你几乎不得不使用一堆样板代码或依赖元编程这对静态语言来说很棘手。
我认为在 95% 的情况下,既然我们有了 JSON 和动态语言之类的东西,那么拥有一堆仅通过实体名称和字段名称来区分的样板是错误的。
关于node.js - 你如何更新 Node.js 中的一对多关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17647112/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack