Как сохранить числовые значения для веса / объема, не получая ошибок округления с плавающей запятой, и конвертировать в единицы (г> кг)? - PullRequest
0 голосов
/ 04 ноября 2019

Мне нужно хранить в Rails-модели PackageType объем и вес. У меня есть две (связанные) проблемы:

  1. Значения не могут быть целыми числами. Например, это может быть 0,5 кг. Но я хочу избежать ошибок округления, связанных с плавающей точкой: после добавления / умножения / деления я не хочу рисковать, получая 1,00000001 кг (в основном по причинам бухгалтерского учета).
  2. У меня возникает желание сохранить этоони как маленькая единица, где они всегда будут целыми числами: граммы и см3. (Я знаю, что мои пакеты не будут меньше 1 г / 1 см3). Но это не очень удобно для пользователя: мои пользователи должны скорее видеть и вводить значения в L (дм3) и в кг.

Решение, которое я нашел на данный момент, состоит в том, чтобы иметь столбцы weight_g и volume_cl:

rails g migration AddVolumeAndWeigthToPackageTypes volume_cm3:integer weight_g:integer

И есть в моей модели несколько методов для преобразования между единицами:

class PackageType < ApplicationRecord
  …
  def volume_dm3
    volume_cm3.to_f / 1000
  end

  def volume_dm3=(vol)
    self.volume_cm3 = (vol*1000).to_i
  end

  def weight_kg
    weight_g.to_f / 1000
  end

  def weight_kg=(w)
    self.weight_g = (w*1000).to_i
  end
end

Это работает, но не правильно, и поднимает нескольковопросы:

  1. Почему в моделях Rails я могу получить доступ к атрибуту модели без обозначения @? Как будто я могу читать то, что хранится, просто вызывая volume_cm3, а не self.volume_cm3 или @ volume_cm3. И почему я могу читать, не ставя себя впереди, но мне нужно уточнить для себя self.volume_cm3, чтобы написать это?
  2. Это правильный способ сделать это, или я должен просто отказаться от этого преобразования и сохранить непосредственно килограммы и л. как десятичные дроби? Я пока не собираюсь отображать пользователей в других единицах, кг и л - единственные единицы, которые я буду использовать. Я испытываю искушение просто использовать десятичные дроби, кг и L.
  3. Когда вам нужно хранить что-то, в котором есть единица измерения, каков рекомендуемый способ именования столбцов базы данных и атрибута модели? Это «объем» (предполагаемая единица измерения), «объем_дм3», «объем_ин_дм3»?

1 Ответ

0 голосов
/ 05 ноября 2019
  1. Нотация @ предназначена для создания переменной экземпляра, чтобы сделать переменные из контроллеров доступными в представлениях. Таким образом, нотация @ не имеет ничего общего с доступом к переменным внутри самой модели. Насколько я знаю, причина, по которой вам нужно указывать self.volume_cm3 при записи в переменную и получать к ней доступ только с помощью volume_cm3, заключается в том, что при написании Rails нужно знать, что вы не создаете локальную переменную с помощьюто же имя, что и атрибут (я бы не рекомендовал его, но я не думаю, что ruby ​​помешает вам сделать это). Таким образом, self.volume_cm3 = 3 установит атрибут volume_cm3, но volume_cm3 = 3 просто создаст локальную переменную со значением 3.

  2. Если вы хотите сохранить данные в виде десятичных дробей,вы всегда можете округлить десятичные дроби, используя '%.Nf' % volume_cm3, где N - это количество цифр, до которого вы хотите округлить десятичную дробь. Так что '%.2f' % 1.345 будет округлять до двух десятичных знаков и давать вам 1.35.

  3. Я не думаю, что у ruby ​​есть конкретное руководство по именованию, когда речь идет о числах и единицах, так что, вероятно,просто вопрос предпочтений. Если у вас есть другие единицы измерения, с которыми вы будете измерять громкость, может быть полезно добавить определенные единицы измерения в конец имени атрибута, чтобы избежать путаницы (например, volume_cm3, volume_L и т. Д.). Если вы измеряете только одну единицу на атрибут, вы можете просто назвать их volume и weight и просто добавить комментарий к модели, объясняющий, что они должны быть в определенных единицах.

...