Ruby number_to_currency отображает совершенно неверное число! - PullRequest
1 голос
/ 08 апреля 2010

Привет! Я старый программист на Delphi, делающий скачок к Mac, Ruby, Rails и веб-программированию в целом. Я записался на семинар Advanced Rails в конце месяца. Тем временем я работал над переносом критически важного (конечно) приложения из Delphi в RAILS. Такое ощущение, что я провел большую часть прошлого года с головой, спрятанной в книге или подкасте.

Прямо сейчас у меня возникла серьезная проблема, и я вырываю волосы. Я буквально не знаю, куда идти с этим, я отчаянно не хочу развертывать с этой ошибкой, и я чувствую себя немного безумным. (База данных компании в настоящее время работает на старом Windows XP, который выглядит все более грязным с каждым днем.)

Итак, я настроил тестовую базу данных, которая показывает проблему. Я бегу:

 OS/X 10.6.3
 Rails 2.3.5
 ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0]
 MySQL 5.1.38-log via socket
 MySQL Client Version 5.1.8

ActiveRecord::Schema.define(:version => 20100406222528) do

     create_table “money”, :force => true do |t|
     t.decimal “amount_due”, :precision => 10, :scale => 2, :default => 0.0
     t.decimal “balance”, :precision => 10, :scale => 2, :default => 0.0
     t.text “memofield”
     t.datetime “created_at”
     t.datetime “updated_at”
     end

Представление индекса прямо из генератора, немного изменено, чтобы добавить форматирование, которое мне мешает.

Listing money
<table>

     <tr>
     <th>Amount</th>
     <th>Amount to_s </th>
     <th>Balance to $</th>
     <th>Balance with_precision </th>
     <th>Memofield</th>
     </tr>

<% @money.each do |money| %>

     <tr>
     <td><%=h money.amount_due %></td>
     <td><%=h money.amount_due.to_s(‘F’) %></td>
     <td><%=h number_to_currency(money.balance) %></td>
     <td><%=h number_with_precision(money.balance, :precision => 2) %></td>
     <td><%=h money.memofield %></td>
     <td><%= link_to ‘Show’, money %></td>
     <td><%= link_to ‘Edit’, edit_money_path(money) %></td>
     <td><%= link_to ‘Destroy’, money, :confirm => ‘Are you sure?’, :method => :delete %></td>
     </tr> *<% end %> *</table>

<%= link_to ‘New money’, new_money_path %>

Казалось, это работает довольно хорошо. Затем я начал тестирование с производственными данными и столкнулся с серьезной проблемой с number_to_currency.

Номер в базе данных: 10542.28, я проверил его с помощью MySQL Query Browser. RAILS будет отображать это как 10542.28 , если только я не позвоню number_to_currency, тогда этот номер будет отображаться как: $ 15422.80

Похоже, ошибка возникает с любым числом от 10 000,00 до 10 999,99. Пока я не видел его за пределами этого диапазона, но, очевидно, я не все проверял.

Полагаю, мой обходной путь - удалить number_to_currency, но это оставляет взгляды действительно небрежными и непрофессиональными. Форматирование сбито с толку, все выстроено неправильно, и я не могу заставить дисплей отображать 2 десятичных знака.

Я серьезно надеюсь, что это легко исправить. Я не могу представить, что это широко распространенная проблема. Это затронет так много людей, что кто-то исправит это! Но я не знаю, куда идти отсюда.

Мне отчаянно нужна помощь.

(Позже - number_with_precision завершается ошибкой так же, как number_to_currency.)

Сью Петерсен

Ответы [ 8 ]

3 голосов
/ 08 апреля 2010

Пока вы не найдете исправления, вы можете сделать свой собственный:)

def formatted_number(n)
  a,b = sprintf("%0.2f", n).split('.')
  a.gsub!(/(\d)(?=(\d{3})+(?!\d))/, '\\1,')
  "$#{a}.#{b}"
end

DATA.each do |n|
  puts formatted_number(n)
end

__END__
1
1.1
1.11
11
11.1
11.11
111
111.1
111.11
1111
1111.1
1111.11
11111
11111.1
11111.11
111111
111111.1
111111.11
1111111
1111111.1
1111111.11
11111111
11111111.1
11111111.11
111111111
111111111.1
111111111.11

Вывод

$1.00
$1.10
$1.11
$11.00
$11.10
$11.11
$111.00
$111.10
$111.11
$1,111.00
$1,111.10
$1,111.11
$11,111.00
$11,111.10
$11,111.11
$111,111.00
$111,111.10
$111,111.11
$1111,111.00
$1111,111.10
$1111,111.11
$1,1111,111.00
$1,1111,111.10
$1,1111,111.11
$11,1111,111.00
$11,1111,111.10
$11,1111,111.11
2 голосов
/ 08 апреля 2010

Может быть связано с этим:

ошибка rails number_to_currency?

1 голос
/ 22 июня 2013
class Float
  def to_currency
    a,b = sprintf("%0.2f", self).split('.')
    a.gsub!(/(\d)(?=(\d{3})+(?!\d))/, '\\1,')
    "$#{a}.#{b}"
  end
end

class Integer
  def to_currency
    a,b = sprintf("%0.2f", self).split('.')
    a.gsub!(/(\d)(?=(\d{3})+(?!\d))/, '\\1,')
    "$#{a}.#{b}"
  end
end

x = [100.236, 2, 123456789.1]
x.each do | n |
  puts x.to_currency
end

# Results
# $100.24
# $2.00
# $123,456,789.10

Я добавил метод to_currency к классам Float и Integer. Возвращает число в виде отформатированной строки.

0 голосов
/ 09 июня 2010

В итоге я загрузил гем rvm на все мои Mac, и теперь я использую ruby ​​1.8.7 p249.Это решило проблему для меня.

Я проверил ошибку в Ruby и нашел ее для дополнительной информации:

http://www.ruby -forum.com / topic / 189053 #827091

cihaks - Похоже, что предложенный ими временный патч очень похож на то, что вы делаете.В любом случае, спасибо за пост и информацию.: -)

0 голосов
/ 08 июня 2010

Я столкнулся с той же проблемой. Кажется, проблема в переводе большого десятичного числа в число с плавающей точкой. Я изменил одну строку в методе formatted_number и смог получить число, отображаемое так, как должно:

a,b = sprintf("%0.#{options[:precision]}f", n).split('.')

было изменено на:

a,b = sprintf("%0.#{options[:precision]}f", n.to_s.to_f).split('.')

Преобразование в строку, а затем в число с плавающей точкой добилось цели. Это странно, но пока основная проблема не будет решена, она будет работать для нас.

0 голосов
/ 10 апреля 2010

И это является ответом, по крайней мере, частичным ответом.

Мне удалось загрузить более новую версию Ruby (ruby 1.8.7 (2010-01-10 patchlevel 249)), и проблема исчезла.Это явно ошибка в Ruby.Теперь мне просто нужно выяснить, как установить более новую версию Ruby в систему на моем MacBook и 2 мини-компьютерах, которые я использовал в качестве тестовых серверов.

0 голосов
/ 09 апреля 2010

@ smotchkkiss Я попробовал оба предложения.Они оба сделали то же самое, что делает number_to_currency в моей системе.Я подозреваю, что это что-то в версии Ruby, которую я использую.

Я провел большую часть дня, пытаясь установить более новую версию Ruby, установленную в моей системе, и, наконец, сдался и сделал полное восстановление системы с Time Machine.Я все еще изучаю причуды Mac, и мне действительно удалось испортить мою установку RubyGems.

@ Эндрю Гримм Я бы хотел оставить это как комментарий.Я не вижу способа сделать это (работает Snow Leopard, Firefox w NoScript).Я потратил не менее 30 минут на просмотр часто задаваемых вопросов, пытаясь найти способ оставить комментарий вместо ответа.Нет

0 голосов
/ 08 апреля 2010

Другое (более причудливое) решение, которое может помочь вам, пока ошибка не будет устранена

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...