ОШИБКА: Ноль не может быть приведен в Fixnum
У меня есть следующая функция для суммирования всех записей :amount
поле в моем Pack
модель для данного пользователя:
user.rb
def total_money_spent_cents
amount = self.packs.map(&:amount).sum
return amount
end
Однако, когда я использую эту функцию, я получаю следующую ошибку:
nil can't be coerced into Fixnum
Какие-либо предложения?
РЕДАКТИРОВАТЬ У меня все еще есть проблемы с Fixnum в моих тестах, и у меня есть еще один вопрос, открытый здесь.
2 ответа
Это говорит о том, что один из ваших пакетов имеет поле количества, которое еще не было установлено, поэтому nil
, Когда вы пытаетесь добавить его к чему-то другому, он подвергается принуждению к типу, чтобы увидеть, может ли Ruby втиснуть свой тип в тип, который может быть добавлен к числам, но не может, и поэтому у вас есть эта ошибка.
Одним из решений является следующее:
def total_amount_spent_cents
packs.map(&:amount).compact.sum
end
Array#compact
удаляет nil
элементы.
Это может быть устранение симптома, а не проблема. Это может быть тот случай, когда вы не должны иметь nil
там вообще, в этом случае вы должны проверить инициализацию вашего Pack
модель (или, возможно, ее проверки, чтобы гарантировать, что amount
является обязательным).
Я добавил несколько дополнительных методов в Array и Hash для такого рода вещей: они как compact
но они удаляют все значения, возвращающие true для blank?
а не просто nil: поэтому удалит пустые строки, пустые массивы, хэши и т. д.
class Hash
def compact_blank!
self.each{|k,v| self.delete(k) if v.blank? }
self
end
def compact_blank
self.dup.compact_blank!
end
end
class Array
def compact_blank!
self.delete_if(&:blank?)
end
def compact_blank
self.dup.compact_blank!
end
end
использовать как
["1", "abc", "", nil, []].compact_blank
=> ["1", "abc"]
особенно полезно с params, где вы можете получить много пустых строк.