Mike Wiesenhart - 2 months ago 14

Ruby Question

I have an

`item`

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>`

Answer

You can use `sold`

scope in the calculation:

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

But each time you call `Item.profit_total`

it will execute all the queries. You may want to cache the calculation if you need that frequently and expire the cache in after_save callback if that is sold.