我应该如何在猫鼬中存储价格?

时间:2012-11-09 07:48:55

标签: node.js mongoose currency

我正在为node.js使用mongoose模式以及express-validator(具有节点验证器santiziations和验证器)。

什么是存储物品价格的好方法?

我目前有

var ItemSchema = new Schema({
    name            : { type: String, required: true, trim: true }
    , price             : Number
});

价格是可选的,所以我有:

  if ( req.body.price ) {
    req.sanitize('price').toFloat();
    req.assert('price', 'Enter a price (number only)').isFloat();
  }

express-validator给我isNumeric(允许0填充),isDecimal和isInt ...我宁愿只转换为十进制并删除所有字符,所以我总是将42.00插入db。

我想允许他们输入42.00美元,42美元,42美元,42.00美元,只需存储42.00美元。我怎么能做到这一点?并且仍然验证我看到类似于数字的内容,例如,如果他们输入'abc',我想使用req.assert将错误返回到表单。

另外,我认为货币最终会成为一个问题......

更新,我发现这篇文章说将价格存储为整数美分,所以4200 https://dba.stackexchange.com/questions/15729/storing-prices-in-sqlite-what-data-type-to-use

我只需要一种方法将4200转换为$ 42.00,当我调用item.price并清理并将输入转换为4200时。

5 个答案:

答案 0 :(得分:24)

这就是我最终做的......

我在数据库中将价格存储为美分,因此如下所述,49.99为4999:https://dba.stackexchange.com/questions/15729/storing-prices-in-sqlite-what-data-type-to-use

getPrice会将其转换回可读格式,因此我可以在我的视图中使用item.price来修改它。

setPrice将其转换为美分。

模型:

var ItemSchema = new Schema({
    name            : { type: String, required: true, trim: true }
    , price             : {type: Number, get: getPrice, set: setPrice }
});

function getPrice(num){
    return (num/100).toFixed(2);
}

function setPrice(num){
    return num*100;
}

我选择只在价格字段中允许数字和小数,而不是$。 所以他们可以输入49,49.99,49.00,但不能输入49.0或49美元

使用正则表达式进行验证:

if ( req.body.price ) {
    req.assert('price', 'Enter a price (numbers only)').regex(/^\d+(\.\d{2})?$/);
}

我希望有一种方法允许$因为我认为它是一个可用性问题,只是让用户输入它,但将其剥离。我不知道该怎么做,仍然确认我们有价格,而不是一堆信件。

答案 1 :(得分:9)

  

提示:此处描述的方法基本上只是chovy's answer的另一种实现。

Mongoose 3& 3的解决方法4:

如果您无法直接在架构中定义getter和setter,您还可以使用schema.path()函数来完成此工作:

<!DOCTYPE html>
<html>
  <head>
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script>
var myCenter=new google.maps.LatLng(45.159457,18.0158902);


function initialize() {
  var mapProp = {
    center:new google.maps.LatLng(45.159457,18.0158902),
    zoom:13,
    mapTypeId:google.maps.MapTypeId.ROADMAP
  };
  var map=new google.maps.Map(document.getElementById("map"),mapProp);

  var marker=new google.maps.Marker({
  position:myCenter,
  });


marker.setMap(map)

}
</script>
<script>

function tagovi(){
var myCenter2=new google.maps.LatLng(45.1568915,18.0153617);
var marker2=new google.maps.Marker({
  position:myCenter2,
  });

marker2.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>   
  <body>
  <div class="b_m"><a href="#" onclick="tagovi()"><img src="slike/restorani.png"></a></div>
  </body>
</html>  

答案 2 :(得分:3)

添加架构类型&#34;货币&#34;为了处理钱而愚弄。自动删除常用字符(&#34;,&#34;,&#34; $&#34;和字母字符)

https://github.com/paulcsmith/mongoose-currency

它的作用:

将字符串保存为整数(通过剥离非数字并乘以100)以防止在执行计算时出现舍入错误(有关详细信息,请参阅gotchas) 从字符串的开头删除符号(有时用户包括货币符号) 删除逗号(有时用户用逗号添加或将粘贴值复制到表单中,例如&#34; 1,000.50) 仅从小数点后的两位数保存(&#34; $ 500.559&#34;转换为50055并且不进行舍入) 从字符串中剥离[a-zA-Z] 传入一个字符串或数字。号码将按原样存储。 假设如果您将值设置为整数,则表示您已完成转换(例如50000 = $ 500.00) 如果传递一个浮点数,它将围绕它。 (500.55 - > 501)。只需传入整数即可。

希望它有所帮助。

答案 3 :(得分:1)

我一直在研究这个话题,因为我不仅要存储价格,还要存储版本,这两个版本都可能有0后跟0,当存储为数字时会被切断。据我所知,Mongoose / MongoDB无法使用尾随零保存数字。

除非您将数字保存为字符串。

除了存储数十或数千的数字以及分割或解析之外,您还可以将其存储为字符串。这意味着,只需使用变量而不需要任何转换就可以在需要显示“1.0”或“1.00”时将其打印出来。由于JavaScript是无类型的,您仍然可以将其与数字进行比较(确保它位于左侧)。 Var&lt;例如,10将返回正确的评估,即使var是一个字符串。如果你要比较两个变量,你需要确保它们都是数字。当你需要一个数字时,你可以将字符串乘以一(var * 1&lt; var2 * 1),这将确保JavaScript将var视为一个数字,尽管它会丢失尾随的零。

一方面,将其存储为字符串意味着每次要将变量用作数字时都需要进行转换。另一方面,每次你想使用美分数作为美元金额时,你可能会进行数字转换(var / 100)。此选项取决于您需要将数值作为数字的频率。如果你忘记你的变量是一个字符串而不是忘记你的变量是美分,它也可能导致更大的错误。

(但是,它非常适合只能用于显示和比较的版本号。)

答案 4 :(得分:0)