开发者

:counter_cache for total items

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: 1

When 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜