ОШИБКА: Ноль не может быть приведен в 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, где вы можете получить много пустых строк.

Другие вопросы по тегам