I hava a simple set of two related tables of an 'order' that has many 'line_items'. There is also a quantity associated to a line item, e.g.
Order1
line_item a: 'basket weaving for beginners', quantity: 3 line_item b: 'a dummies guide to vampirism', quantity: 1When I establish the migration I can include the quantity using:
Order.find(:all).each do |o|
o.update_attribute :line_items_count, o.line_items.map(&:quantity).sum
end
which gives me the correct number of ite开发者_运维百科ms (4), but I don't appear to be able to do it on the Order model because I'm unable to pass in the quantity of line items, and so it just counts the number of line items (2).
So in the line_item model I have:
belongs_to :order, :counter_cache => true
Is there any way I can specify the quantity so that it correctly says 4 instead of 2?
The 'counter_cache` feature to meant to maintain the count(not the sum) of dependent items.
You can easily achieve this by writing few lines of ruby code.
Let us assume that you have a column called line_items_sum
in your orders
table. The value of this column should default to 0.
class AddLineItemsSumToOrder < ActiveRecord::Migration
def self.up
add_column :orders, :line_items_sum, :integer, :default => 0
end
def self.down
remove_column :orders, :line_items_sum
end
end
class Order < ActiveRecord::Base
has_many :line_items
end
Now add the callback to the LineItem
class.
class LineItem < ActiveRecord::Base
validates_numericality_of :quantity
belongs_to :order
after_save :update_line_items_sum
private
def update_line_items_sum
return true unless quantity_changed?
Order.update_counters order.id,
:line_items_sum => (quantity - (quantity_was || 0))
return true
end
end
I think your best bet would be to write your own method for caching the total quantity. If you don't follow the "Rails way" for keeping the counter, you're better off writing your own.
精彩评论