Отслеживание суммы некоторых полей в ассоциации - "sum_cache"

У меня есть таблицы 'orders' и 'items' с ассоциацией has_many в модели.

class Order < ActiveRecord::Base
has_many :items

class Item < ActiveRecord::Base
belongs_to :order

Элемент состоит из поля "количество", а Заказ состоит из поля "количество_сум" для отслеживания суммы количества связанных элементов.

Например:

Order 1 : name='Toms shopping cart', quantity_sum=12
Item 1 : name='T-shirt', quantity=10
Itme 2 : name='Shoes',   quantity=2

Я искал способ, чтобы всякий раз, когда новый элемент добавлялся / редактировался / удалялся, поле "количество_суммы" заказа обновлялось автоматически. В настоящее время я использую метод after_save в Item, чтобы обновить поле "amount_sum" в Order.

Есть ли другой аккуратный способ сделать это, кроме 'after_save'???

Аналогично "counter_cache" для отслеживания количества ассоциаций, есть ли в rails поддержка автоматического отслеживания суммы некоторых полей в ассоциации?

Спасибо

2 ответа

Удалите поле amount_sum из своей таблицы и добавьте метод amount_sum к классу заказа, который суммирует количественное значение

class Order < ActiveRecord::Base
  has_many :items

  def quantity_sum
    self.items.sum(:quantity)
  end
end

Должен сделать свое дело. Все, что вам нужно сделать, это удалить любой код, который у вас есть, который обновляет поле amount_sum. Вы обнаружите, что, поскольку имя метода совпадает с именем поля (которое вы не должны забыть удалить), вам не придется реорганизовывать любой код, который его использует.

Очевидно, что вы должны быть осторожны, чтобы не использовать это поле излишне, как в списке всех заказов в системе, так как это будет довольно тяжело для базы данных. Хорошо для нескольких сотен записей, но вы заметите проблему с производительностью более тысячи заказов.

Не забудьте удалить это поле количества из таблицы заказов

Я думаю, что этот драгоценный камень - то, что вы ищете.
Посмотрите под "Итоги вместо того, чтобы считать" в документах.
Это должно позволить вам что-то вроде этого:

class Item < ActiveRecord::Base
  belongs_to :order
  counter_culture :order, :column_name => 'quantity_sum', :delta_column => 'quantity'
end

class Order < ActiveRecord::Base
  has_many :items
end
Другие вопросы по тегам