web-dev-qa-db-ja.com

マングースで価格を保存するにはどうすればよいですか?

Node.jsのmongooseスキーマを、express-validator(node-validator santiziationsとvalidatorsを含む)とともに使用しています。

アイテムの価格を保存する良い方法は何ですか?

私は現在持っています

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を与えます... 10進数に変換してすべての文字を削除したいので、dbに常に42.00を挿入します。

私は、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-使用する

Item.priceを呼び出すときに4200を42.00ドルに変換し、入力をサニタイズして4200に変換する方法が必要です。

20
chovy

ヒント:ここで説明する方法は、基本的には chovy's answer の別の実装です。

Mongoose 3&4の回避策:

スキーマでゲッターとセッターを直接定義するのに問題がある場合は、 schema.path() 関数を使用してこれを機能させることもできます。

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

// Getter
ItemSchema.path('price').get(function(num) {
  return (num / 100).toFixed(2);
});

// Setter
ItemSchema.path('price').set(function(num) {
  return num * 100;
});
10
ofhouse

これは私がやったことです...

私はデータベースにセントとして価格を保存したので、ここで説明されているように49.99に対して4999です。 https://dba.stackexchange.com/questions/15729/storing-prices-in-sqlite-what-data-type-使用する

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})?$/);
}

使いやすさの問題だと思うので、$を許可する方法があったらいいのにと思います。ユーザーに入力させて、それを取り除きます。どのようにすればよいのかわからないが、たとえば、文字の束ではなく、価格があることを検証する。

25
chovy

お金を処理するためにスキーマタイプ「通貨」をマングースに追加します。一般的な文字( "、"、 "$"およびアルファベット文字)を自動的に取り除きます

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

それがすること:

文字列を整数として保存し(非数字を取り除き、100を掛けることで)、計算の実行時の丸めエラーを防止します(詳細はgotchasを参照)文字列の先頭から記号を取り除きます(ユーザーが通貨記号を含む場合があります)ユーザーがカンマを追加するか、値をフォームにコピーして貼り付けます(例: "1,000.50)小数点以下2桁からのみ保存(" $ 500.559 "は50055に変換され、四捨五入されません)文字列から[a-zA-Z]を削除します文字列または数値。数値は現状のまま保存されます。値を整数に設定した場合は、すでに変換が行われていると想定します(例:50000 = $ 500.00)浮動小数点数が渡されると、四捨五入されます(500.55 -> 501)。安全のために整数を渡すだけです。

それがいくらか役に立てば幸いです1。

3
Dionis Olen

価格だけでなくバージョンも保存したいので、このトピックについてしばらく調査してきました。どちらも、数値として保存すると切り捨てられる末尾の0がある場合があります。私の知る限り、Mongoose/MongoDBは、末尾にゼロがある数字を保存できません。

数値を文字列として保存しない限り。

数十または数千の数値を格納したり、除算または解析したりする以外に、文字列として格納することもできます。つまり、変換せずに変数を使用するだけで、「1.0」または「1.00」を表示する必要がある場合は、いつでも印刷できます。 JavaScriptは型指定されていないため、数値と比較することができます(左側にあることを確認してください)。たとえば、Var <10は、varが文字列の場合でも正しい評価を返します。ただし、2つの変数を比較する場合は、両方が数値であることを確認する必要があります。数値が必要な場合、文字列に1を掛けることができます(var * 1 <var2 * 1)。これにより、JavaScriptがvarを数値として処理することを保証しますが、末尾のゼロは失われます。

一方、文字列として格納することは、変数を数値として使用するたびに変換を行う必要があることを意味します。一方、セントの数値をドルの金額として使用するたびに、おそらく数値変換(var/100)を実行することになります。このオプションは、数値としての値に必要な頻度に依存します。また、変数がセント単位であることを忘れた場合よりも、変数が文字列であることを忘れた場合の方が大きなバグを引き起こす可能性があります。

(ただし、これは表示と比較にのみ使用されるバージョン番号に最適です。)

1
ansorensen

numeralモジュールはそれを達成します: http://numeraljs.com/https:// www。 npmjs.com/package/numeral

0
Francesco