2012-11-15 149 views
2

我是新来的rails,并且正在开发我的第一个rails项目之一,它是发票窗体中嵌套行项目的发票应用程序。我想在保存发票之前计算总发票。如果只是在保存过程中添加了项目,我可以很好地保存它,但如果其中一个嵌套行项目被标记为删除,则不会正确计算总计。我将不得不返回并再次保存以获得正确的总计费用。Rails嵌套窗体,在嵌套项目中计算值

class Invoice < ActiveRecord::Base 
    attr_accessible :job_name, :items_attributes, :tax1, :tax2, :subtotal 

    before_save :calculate_totals 


    has_many :items, :dependent => :destroy 
    accepts_nested_attributes_for :items, allow_destroy: true 

    private 

    def calculate_totals 
    self.subtotal = 0 

    self.items.each do |i| 
     self.subtotal = self.subtotal + (i.quantity * i.cost_per) 
    end 
    end 
end 

我注意到这是如何不同于PARAMS但问题条目记录与请求PARAMATERS上市:_destroy =真

{"utf8"=>"✓", 
"_method"=>"put", 
"authenticity_token"=>"+OqRa7vRa1CKPMCdBrjhvU6jzMH1zQ=", 
"invoice"=>{"client_id"=>"1", 
"job_name"=>"dsdsadsad", 
"items_attributes"=>{"0"=>{"name"=>"jhksadhshdkjhkjdh", 
"quantity"=>"1", 
"cost_per"=>"50.0", 
"id"=>"21", 
"_destroy"=>"false"}, 
"1"=>{"name"=>"delete this one", 
"quantity"=>"1", 
"cost_per"=>"10.0", 
"id"=>"24", 
"_destroy"=>"true"}}}, 
"commit"=>"Update Invoice", 
"id"=>"8"} 

感谢您帮助。

回答

2

我发现,似乎工作的解决方案:

class Invoice < ActiveRecord::Base 
    attr_accessible :job_name, :items_attributes, :tax1, :tax2, :subtotal 

    before_save :calculate_totals 


    has_many :items, :dependent => :destroy 
    accepts_nested_attributes_for :items, allow_destroy: true 

    private 
    def calculate_totals 
     self.subtotal = 0 

     self.items.each do |i| 
     unless i.marked_for_destruction? 
      self.subtotal += (i.quantity * i.cost_per) 
     end 
     end 

end 

的关键是方法marked_for_destruction?在这种情况下,我正在检查没有标记为销毁的物品。下面是解释它的轨道API链接:http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

感谢 史蒂夫

+0

感谢您编写此解决方案,它帮助我解决了我的问题 – widjajayd

0
params[:invoice][:items_attributes].each do |i| 
    self.subtotal = self.subtotal + (i[:quantity].to_f * i[:cost_per].to_f) unless i['_destroy'] == 'true' 
end 
+0

当我尝试这样做我得到未定义的局部变量或方法'PARAMS'为#<发票:0x00000103d0b9d0>,在模型中可用PARAMS ?我可以在调用update_attributes之前添加raise params.inspect,如果在calulate_totals方法中添加了相同的项目,我会得到与上面相同的错误 – Steve

+0

yep那是错误的,您的解决方案对我来说很合适 – f1sherman

0

您已经计算项目Invoice之前被保存,所以计算出项目的API文档中被破坏过,作为具有指导:

注意,该模型将不会被破坏,直到父保存。

所以你只需要改变before_saveafter_save,它会起作用。

+0

哎Kien,我试过这个,它从不更新小计,即使没有记录标记为detstroy。我是否应该将after_save移至项目模型? – Steve

+0

当您的发票未保存时,您是否意味着它在浏览器中更新?发票保存后,它是否计算正确的小计? – Thanh

+0

它根本没有更新小计 – Steve