2012-11-15 165 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