Расчет в модели не работает для задачи rake

У меня есть метод/действие/фрагмент кода (я всегда немного теряюсь в терминологии рельсов), настроенный в моей модели для обновления суммы, оставшейся в бюджете, при вводе нового объявления.

class Budget < ActiveRecord::Base
belongs_to :client
has_many :adverts
before_save :update_budget

validates :name, :amount, :client_id, presence: true

def update_budget
    self.amount_remaining = self.amount - self.amount_spent
end
end

Это прекрасно работает при обновлении моих бюджетов или вводе нового объявления. Все работает как надо. Тем не менее, я написал задачу rake, чтобы записать список повторяющихся бюджетов в таблицу бюджета (чтобы я мог планировать это ежемесячно). Однако, когда я запускаю эту задачу из терминала, возникает ошибка.

Задача грабли.

desc "Recurring Updates"
task :recurring_budgets => :environment do
    @recurring_budgets = RecurringBudget.all
    @recurring_budgets.each do |recurring_budget|
        Budget.create(name: recurring_budget.name, amount: recurring_budget.amount, client_id: recurring_budget.client_id)
    end
end

Ошибка.

$ rake recurring_budgets
rake aborted!
TypeError: nil can't be coerced into Fixnum
/Users/tomgamon/projects/adsman/app/models/budget.rb:9:in `-'
/Users/tomgamon/projects/adsman/app/models/budget.rb:9:in `update_budget'
/Users/tomgamon/projects/adsman/lib/tasks/recurring_budgets.rake:6:in `block (2 levels) in <top (required)>'
/Users/tomgamon/projects/adsman/lib/tasks/recurring_budgets.rake:5:in `block in <top (required)>'
Tasks: TOP => recurring_budgets
(See full trace by running task with --trace)

Стоит отметить, что когда я удаляю метод из своей модели, задача записывает в таблицу бюджетов нормально.

У кого-нибудь есть идеи?


person thrgamon    schedule 06.03.2016    source источник


Ответы (1)


Это связано с тем, что вы пытались minus nil из amount

update_budget вызвал before_save callback - и здесь вы вычисляете amount_remaining с вычитанием amount_spent из amount в вашем случае amount_spent равно nil, поэтому, когда вы пытаетесь вычесть значение nil из чего-то, вы получите эту ошибку - TypeError: nil can't be coerced into Fixnum

Для этого есть два решения -

1 - если amount_spent равно nil, вы должны использовать 0

def update_budget
    self.amount_remaining = self.amount - (self.amount_spent || 0)
end

ИЛИ

2 — вы можете установить значения по умолчанию для amount_remaining, amountи amount_spent как 0(ноль) при миграции.

Для таких полей лучше установить значения по умолчанию, а не проверять nil значений в коде.

person Sampat Badhe    schedule 06.03.2016
comment
Блестящий. Я добавил значения по умолчанию в свою таблицу, и теперь она отлично работает. Спасибо! - person thrgamon; 06.03.2016