2014-12-19 2 views
0

Я работаю над отчетами для веб-сайта, и сейчас я думаю о том, каким будет лучший способ обработки BigDecimal -0.0.BigDecimal to Currency с -0.0

В базе данных, с которой я работаю, их много. Когда эти -0.0 отправляются через number_to_currency(), я получаю «$ -0.00». Мой формат для отрицательных чисел на самом деле «- $ x.xx», поэтому обратите внимание, что number_to_currency не форматирует его как отрицательное число (иначе также будет отрицательный знак перед значком доллара), но по какой-то причине отрицательный знак переводится вместе с 0.

Сейчас мое решение, чтобы сделать это каждый раз, когда я получаю сумму из базы данных:

amount *= -1 if amount == 0 && amount.sign == -1 

Это изменяет -0.0 до 0.0. Это достаточно просто, но я не могу не задаться вопросом, есть ли лучшее решение, или что-то в BigDecimals или number_to_currency, чтобы справиться с этой ситуацией, которую я просто не нахожу.

+1

Что расчет вы делаете, чтобы сохранить $ -0,0 в вашей базе данных? Когда я делаю '(BigDecimal.new (« 50.00 ») + BigDecimal.new (« - 50.00 »)). Zero?' Я получаю 'true' – Anthony

+0

@ Энтони - Я не знаю, как -0.0 хранится в база данных. Я работаю с базой данных, которую я не создавал, купите мой следующий шаг, чтобы исследовать это. Если я смогу избежать его хранения, это сэкономит мне много работы. В противном случае Сайед дал мне довольно тщательный ответ и лучший способ написать мое решение. – Isaac

+1

Если у вас есть какие-либо слова, я бы поговорил с командой, напишу переход, чтобы преобразовать все -0.0 в 0.0 в базу данных, а затем не придется беспокоиться о какой-либо из этих логик представления. Очевидно, что это требует, чтобы вы правильно сохранили его в db, продвигаясь вперед. – Anthony

ответ

2

Это потому, что число преобразуется в строку для отображения. И:

# to_d converts to BigDecimal, just FYI 
"-0".to_d.to_s #=> "-0.0" 

Поэтому вам нужно будет сделать это самостоятельно. Но знак-проверки являются избыточными - простое сравнение с 0 будет делать трюк:

bdn = "-0".to_d # or BigDecimal.new("-0") 
value = bdn.zero? ? 0 : bdn 
number_to_currency(value, other_options) 

Однако, вы не хотели бы, чтобы вручную добавить эту проверку везде вы звоните number_to_currency. Было бы удобнее, чтобы создать свой собственный modified_number_to_currency метод, в вашем ApplicationHelper, например, так:

def modified_number_to_currency(number, options) 
    value = number.zero? ? 0 : number 
    number_to_currency(value, options) 
end 

И затем использовать modified_number_to_currency вместо number_to_currency.

В качестве альтернативы, вы можете перезаписать number_to_currency и позвонить ему super. То, что может также работает, но я не уверен на 100%.

Далее в чеке именно:

amount *= -1 if amount == 0 && amount.sign == -1 

Это должно быть просто:

amount = 0.to_d if amount.zero? # the to_d might or might not be required 
+0

Это потрясающе. Спасибо. Вы подтвердили много вещей, которые я думал, и сделали мой чек еще лучше. И .to_d не требуется. Я попытаюсь изучить, как эти BigDecimals хранятся в базе данных, и, надеюсь, я могу избежать хранения -0. Это позволит избежать необходимости проверки вообще. – Isaac

+0

Он хранился в порядке 0,0, но одна из моделей применяла * -1, если транзакция имела тип «КРЕДИТ». Я добавил проверку метода, чтобы сначала увидеть, является ли это .zero? Все мои «$ -0,00» ушли сейчас :) – Isaac

+0

При использовании 'modified_number_to_currency' полезно сохранить параметры по умолчанию' options = {} ', или если проблемы не будут заданы, могут возникнуть проблемы. – silverdr