2016-11-12 5 views
0

Ich habe ein item Modell und muss den Gesamtgewinn abzüglich aller Gebühren berechnen. Das mache ich momentan gerade im Modell. Ich möchte jedoch, dass diese Berechnung nur ausgeführt werden kann, wenn der Boolesche Wert auf "Verkauft" gesetzt wird. Ich habe eine if-Anweisung im Modell versucht, aber das hat nicht funktioniert.Schienen Modellberechnung nur wenn Bedingung erfüllt

item.rb

class Item < ActiveRecord::Base 
    def profit_calc 
    sold_for - bought_for - fees - shipping rescue 0 
    end 

    def self.purchase_total 
    sum(:bought_for) 
    end 

    def self.fee_total 
    sum(:fees) 
    end 

    def self.shipping_total 
    sum(:shipping) 
    end 

    def self.sales_total 
    sum(:sold_for) 
    end 

    def self.profit_total 
    sum(:sold_for) - sum(:bought_for) - sum(:fees) - sum(:shipping) 
    end 

    scope :visible, -> { where(sold: false) } 
    scope :sold, -> { where(sold: true) } 
end 

schema.rb

create_table "items", force: :cascade do |t| 
    t.string "description" 
    t.float "bought_for" 
    t.float "sold_for" 
    t.float "fees" 
    t.float "shipping" 
    t.datetime "created_at",       null: false 
    t.datetime "updated_at",       null: false 
    t.boolean "sold",    default: false 
end 

statistics.html.erb

<td><%= number_to_currency(@items.profit_total) %></td> 
+0

Möchten Sie 'total_profit' in der Datenbank nach der Berechnung speichern? – Muntasim

+0

@Muntasim Nein, das ist nicht notwendig. –

+0

@MikeWiesenhart können Sie 'after_save' mit der Bedingung' if:: sell_changed? 'Verwenden und innerhalb der Callback-Methode' do ... something self.sold? ' – dp7

Antwort

1

Sie sold Umfang bei der Berechnung verwendet werden können:

def self.profit_total 
    sold.sum(:sold_for) - sold.sum(:bought_for) - sold.sum(:fees) - sold.sum(:shipping) 
    end 

Aber jedes Mal, wenn Sie Item.profit_total aufrufen, wird es alle Abfragen ausführen. Sie können die Berechnung zwischenspeichern, wenn Sie diese häufig benötigen, und den Cache im after_save-Callback ablaufen lassen, wenn dieser verkauft wird.

+1

Das funktioniert perfekt. Vielen Dank! –

Verwandte Themen