Отслеживание суммы некоторых полей в ассоциации - "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