我正在制作一个带有Twilio的MEAN应用程序,该应用程序允许人们通过在应用程序中输入自己的名字来签署在线请愿书。人们只能签名一次请愿书。我计划通过每个电话号码仅允许一个签名来确保这一点。
每次请愿书签名后,都会创建一个像这样的Mongo对象:
{
"_id" : ObjectId("5c5a47ae8f04f9148f43b033"),
"name" : "John Doe",
"number" : "+18373987466",
"date" : "2/5/19"
}
我已经将number
字段转换为唯一索引,因此每个电话号码只能有签名。
我遇到的问题是当某人尝试多次签署请愿书时该怎么办。我想拦截他们的企图,并向他们发送一条消息,说他们已经签署了请愿书。
我看到有两个选择:
选项1 查询数据库以查看是否已输入相同的数字。
这看起来应该很容易,但是我不知道该怎么做。
var number = '+18373987466';
if(collection.find({"number":number}) {
twiml.message("You have already signed the petition");
}
我在这里的想法是,collection.find({"number":number})
如果发现条目具有相同的编号,则将返回true
。但是,它将返回整个Mongo光标。
选项2
由于number
是唯一索引,因此如果使用相同的值创建另一个对象,Mongo将引发错误。我可以拦截抛出的错误,然后向用户发送消息。
我对这种方法的第一个问题是:故意允许您的应用抛出错误是否是好的软件设计?
我使用try/catch
块尝试了这种方法,但是引发的错误立即使应用程序崩溃。
try {
collection.insertOne(
{name : name, number : number, date: dateSigned},
function(error, result) {
console.log(`${name} has been added to the database`);
});
} catch (error) {
// handle error
}
这不是“捕获”错误并防止其崩溃的正确方法吗?
答案 0 :(得分:2)
选项1
所描述的行为是正确的,如果您使用collection.find()
,MongoDB将返回一个游标。您可以使用collection.count()。但是,由于您仅对至少已经有一个值感兴趣,因此可以调用cursor.limit(1)
。
if (collection.find({"number":number}).limit(1).length === 1)
twiml.message("You have already signed the petition");
选项#2
故意允许您的应用抛出 错误?
不。我认为这个设计不好。如果该条目已经存在,则我不会将其视为错误,而是需要特殊处理的情况。如果您使用catch()
,则仍然需要检查将哪种错误发送给用户正确的错误。
假设您的数据库无法访问,因此您无法插入新值,这将是一个(实际的)错误,您应该catch()它。