I'm working on a shopping cart application and I've run into a design question:
I have a field in the cart_lines table called total_price. That field is really just a calculated field based on qty and unit_price. If either of those values change, total_price should also be updated.
The way that makes the most sense to me is to write a method called total_price that defines how it should be calculated rather than modify the value directly from both the qty= and unit_price= methods. The problem is, I want that value stamped in the database so I can use it as a condition or sort field in queries.
I've written the following code (which works fine) that loops through the object's attributes, checks to see if a method exists with the same name, and updates the value if it's different:
class CartLine < ActiveRecord::Base before_save :recalculate
def total_price qty * unit_price end
def recalculate attributes.each do |attribute_name, attribute_value| if respond_to_without_attributes? attribute_name method_value = send(attribute_name) send(attribute_name + "=", method_value) if method_value != attribute_value end end end end
That's fine and it works well but I'm wondering if I'm missing something or there's a simpler way to handle this since I'm going to have to reuse that code all over the place. If not, I could just refactor it to a plugin but I'd be surprised since it sounds like it would be a common situation.
How would you handle this? Any ideas or insight would be appreciated. Thanks!