Reputation: 730
I have the following Structure: An Order
has_many
sales (and a Sale
belongs_to
an Order
).
quantity
and a price
column.totalprice
columnThe totalprice
is composed by price
x quantity
x 12
out of the sales records that belonging to the parent Order
.
This is how my calculation looks inside the Order model:
class Order < ActiveRecord::Base
has_many :sales, dependent: :destroy
after_save :calc
def price
sales.to_a.sum { |item| item.price }
end
def totalpricex12
totalpricex12 = price*12
end
def totaldiscount
sales.to_a.sum { |item| item.discount }
end
def calc
calc = (totalpricex12.to_f)-(totaldiscount.to_f)
self.update_columns(totalprice: calc)
end
end
The problem is: totalprice
only gets updated, when the Order
gets updated or saved, but not if a new Sale
gets added or deleted.
Upvotes: 1
Views: 1947
Reputation: 76784
You'll want to use inverse_of
:
#app/models/sale.rb
class Sale < ActiveRecord::Base
belongs_to :order, inverse_of: :sales
validates :order, presence: true
after_create :update_order
after_destroy :update_order
private
def update_order
order.calc
end
end
#app/models/order.rb
class Order < ActiveRecord::Base
has_many :sales, inverse_of: :order
end
This will give you the respective objects associated to sale
/ order
, which will be made available through the inverse_of
method:
When we call
criminal.prison
without:inverse_of
on both the:belongs_to
and:has_many
associations, it will hit the database. With:inverse_of
, if we already have that prison record in memory thencriminal.prison
will point to the same prison.
Upvotes: 6
Reputation: 2113
You can use after_save
callback, for example like this:
class Sale < ...
belongs_to :order
after_save do
order.calc
end
end
of like this:
class Sale < ...
belongs_to :order
after_save :update_order
def update_order
# call parent to self-update or something like this
end
end
Upvotes: 1