Подтвердить что ты не робот

Как я должен хранить цену в мангусте?

Я использую схемы мангуста для node.js вместе с express-validator (который имеет node -атификаторы и валидаторы).

Какой хороший способ сохранить стоимость товара?

В настоящее время у меня

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 padding), isDecimal и isInt... Я бы предпочел просто преобразовать в десятичную строку и удалить все символы, поэтому я всегда вставляю 42.00 в db.

Я хочу разрешить им вводить $42.00, $42, 42, 42.00 и просто хранить 42.00. Как я могу это сделать? и все еще проверяем, что я вижу нечто похожее на число, например, если они вводят "abc". Я хочу вернуть ошибку в форму, используя req.assert.

Кроме того, я полагаю, что валюта в конечном итоге станет проблемой...

Обновление, я нашел это сообщение, которое говорит, чтобы хранить цену как целое в центах, поэтому 4200 https://dba.stackexchange.com/info/15729/storing-prices-in-sqlite-what-data-type-to-use

Мне просто нужен способ конвертировать 4200 в $42.00, когда я вызываю item.price, а также дезинфицирую и конвертирую вход в 4200.

4b9b3361

Ответ 1

Подсказка: Метод, описанный здесь, представляет собой просто еще одну реализацию chovy 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;
});

Ответ 2

Вот что я в итоге сделал...

Я сохранил цену в центах в базе данных, так что это 4999 за 49,99, как описано здесь: 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})?$/);
}

Я хочу, чтобы был способ разрешить $, потому что я думаю, что это проблема удобства использования, просто позвольте пользователю ввести его, но отключите его. Я не уверен, как это сделать и все еще проверяю, что у нас есть цена, а не куча букв, например.

Ответ 3

Добавляет тип схемы "Валюта" в мангуст для обработки денег. Автоматически выводит общие символы ( ",", "$" и символы алфавита)

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

Что он делает:

Сохраняет String как целое число (путем удаления незаряженных цифр и умножения на 100) для предотвращения ошибок округления при выполнении вычислений (подробности см. в файле gotchas) Выделяет символы с начала строк (иногда пользователи включают символ валюты) Вырезает запятые (иногда пользователи добавляют запятые или копируют значения в формы, например "1000.50) Сохранять только две цифры после десятичной точки ( "$ 500.559" конвертируется в 50055 и не округляется) Полосы [a-zA-Z] из строк Передайте строку или число. Номера будут храниться КАК ЕСТЬ. Предполагается, что если вы установите значение в целое число, которое вы уже выполнили преобразование (например, 50000 = 500,00 долларов США) Если число с плавающей запятой передано, оно будет округлено. (500,55 → 501). Просто передайте целые числа, чтобы быть в безопасности.

Надеюсь, что это поможет some1.

Ответ 4

Я некоторое время занимался изучением этой темы, потому что хочу хранить не только цену, но и версию, которая может иметь завершающие 0s, которые отрубаются при сохранении в виде числа. Насколько мне известно, Mongoose/MongoDB не может сохранить число с конечными нулями.

Если вы не сохраните номер в виде строки.

Помимо хранения чисел в десятках или тысячах и деления или разбора, вы также можете сохранить его как строку. Это означает, что вы всегда можете распечатать его, когда вам нужно показать "1.0" или "1.00", просто используя переменную без какого-либо преобразования. Из-за того, что JavaScript является нетипизированным, вы все равно можете сравнить его с числами (убедитесь, что это с левой стороны). Var < 10, например, вернет правильную оценку, даже если var является строкой. Если вы сравниваете две переменные, вам нужно убедиться, что они оба являются номерами. Когда вам нужно число, вы можете умножить строку на одну (var * 1 < var2 * 1), которая гарантирует, что JavaScript обрабатывает var как число, хотя он потеряет завершающие нули.

С одной стороны, сохранение его в виде строки означает, что вам нужно делать преобразование каждый раз, когда вы хотите использовать переменную как число. С другой стороны, вы предположительно будете делать числовое преобразование в любом случае (var/100) каждый раз, когда хотите использовать число центов в виде суммы в долларах. Этот параметр будет зависеть от того, как часто вам нужно ваше значение как число. Кроме того, это может привести к большим ошибкам, если вы забудете, что ваша переменная является строкой, чем если бы вы забыли, что ваша переменная находится в центах.

(Тем не менее, он отлично подходит для номеров версий, которые будут использоваться только для отображения и сравнения).