Неверный вывод при чтении десятичного значения из базы данных

У меня странная проблема, которую я просто не могу понять. У меня есть валюты, хранящиеся в моей базе данных в виде десятичной дроби. Я читаю из файла CSV и преобразовываю строку в десятичную для сохранения в базе данных. Кажется, что значения не сохраняются правильно при проверке базы данных, большинство сохраняются правильно, но по какой-то причине у меня есть значение 1000, которое хранится как 1, а 2299 - как 2, поэтому, очевидно, существуют проблемы с числами свыше 999,99.

Я запустил миграцию базы данных следующим образом:

def self.up
change_column(:transactions, :in, :decimal, :precision => 8, :scale => 2 )
change_column(:transactions, :out, :decimal, :precision => 8, :scale => 2)
end

Вот код, используемый для хранения значения из файла CSV:

def create

data = params[:dump][:file].read

FasterCSV.parse(data, :headers => true) do |row|

  transaction = Transaction.new
  transaction.date = Date.strptime(row[0], "%d/%m/%Y")
  transaction.transaction_type = row[4]
  transaction.details = row[3]

  if row[7].to_f < 0
    transaction.out = row[7].to_d.abs
  else
    transaction.in = row[7].to_d.abs
  end
  transaction.save

(.Abs заключается в том, что значения вывода денег просто сохраняются как отрицательные значения в файле CSV).

Когда я использую консоль, чтобы создать новую транзакцию и преобразовать строку 1000 и сохранить ее, используя тот же метод, однако, тогда это прекрасно работает, и значение сохраняется как 1000.0.

Кто-нибудь знает, почему это будет? У меня не было бы, хотя это проблема FasterCSV, но я полагаю, что это возможно, если номера CSV не читаются должным образом.

Спасибо за любую помощь,

Том

1 ответ

Решение

Вы смотрели на необработанные данные CSV для строки со значением>= 1000? Мне кажется, что данные отформатированы запятыми каждые 3 цифры, а to_d Метод будет игнорировать все после первой запятой в этом случае.

>> '1,123.41'.to_d
=> #<BigDecimal:10593e0a8,'0.1E1',9(18)>

Если это проблема, просто удалите запятые, используя gsub,

>> '1,123.41'.gsub(',','').to_d
=> #<BigDecimal:105932398,'0.112341E4',18(18)>
Другие вопросы по тегам