Ruby on Rails - 在accepts_nested_attributes_for上计算before_save

时间:2022-08-10 01:19:56

I have an invoice model, that "has many" invoice items. I have a form that allows you to create/edit an invoice, and this form accepts nested attributes for the invoice items.

我有一个发票模型,“有很多”发票项目。我有一个表单,允许您创建/编辑发票,此表单接受发票项目的嵌套属性。

In my invoice model, there is a "total_amount" field that is a calculated field (the sum of "amount" from the invoice items).

在我的发票模型中,有一个“total_amount”字段,它是一个计算字段(发票项目中“金额”的总和)。

I want to calculate this amount when an invoice is created, or updated. I am trying to do this in the before_save event of my invoice model. The code below almost works, however the total that gets saved is always one step behind. I.e. if I have an invoice with a total of $20, and I edit this invoice and change the invoice items to total $15, then save my invoice, the total doesn't change. If I open the same invoice, and then save it again, the total is updated properly.

我想在创建或更新发票时计算此金额。我试图在发票模型的before_save事件中执行此操作。下面的代码几乎可以工作,但是保存的总数总是落后一步。即如果我的发票总额为20美元,我编辑此发票并将发票项目更改为总计15美元,然后保存我的发票,总额不会更改。如果我打开相同的发票,然后再次保存,则总计会正确更新。

I assume that my line below that calculates the sum is accessing the line items that are saved in the database already, and not those that have just been changed and are about to be saved. I don't however know how to access those.

我假设我的下面的行计算总和是访问已经保存在数据库中的行项目,而不是那些刚刚更改并即将保存的行项目。但我不知道如何访问它们。

class Invoice < ActiveRecord::Base
  has_many :invoice_items, :dependent => :destroy

  accepts_nested_attributes_for :invoice_items, :allow_destroy => true 

  before_save :record_total_amount

  private
    def record_total_amount
      self.total_amount = self.invoice_items.sum('amount')
    end
end

Any help would be much appreciated.

任何帮助将非常感激。

3 个解决方案

#1


5  

I solved this problem, I had to replace the calculation line with this one:

我解决了这个问题,我不得不用这个替换计算行:

self.total_amount = invoice_items.map(&:amount).sum

#2


4  

Try this:

self.total_amount = invoice_items.reject(&:marked_for_destruction?).map(&:amount).sum

self.total_amount = invoice_items.reject(&:marked_for_destruction?)。map(&:amount).sum

#3


0  

I know it's a little late, but maybe someone can benefit. Check the logs to see the order of db operations. I had a similar problem where the insertion of nested models were performed after the save operation of the parent model which resulted to similar results.

我知道这有点晚了,但也许有人可以受益。检查日志以查看数据库操作的顺序。我有一个类似的问题,在父模型的保存操作之后执行嵌套模型的插入,导致类似的结果。

#1


5  

I solved this problem, I had to replace the calculation line with this one:

我解决了这个问题,我不得不用这个替换计算行:

self.total_amount = invoice_items.map(&:amount).sum

#2


4  

Try this:

self.total_amount = invoice_items.reject(&:marked_for_destruction?).map(&:amount).sum

self.total_amount = invoice_items.reject(&:marked_for_destruction?)。map(&:amount).sum

#3


0  

I know it's a little late, but maybe someone can benefit. Check the logs to see the order of db operations. I had a similar problem where the insertion of nested models were performed after the save operation of the parent model which resulted to similar results.

我知道这有点晚了,但也许有人可以受益。检查日志以查看数据库操作的顺序。我有一个类似的问题,在父模型的保存操作之后执行嵌套模型的插入,导致类似的结果。