0

Я создаю приложение событий с использованием Rails и добавил связь counter_cache между моделями Event и Booking, чтобы зафиксировать количество заказов, сделанных на каждом мероприятии ,Рельсы - как включить резервирование количества с помощью counter_cache и правильно обновить

Как я могу, чтобы counter_cache правильно обновлялся, когда можно было сделать несколько бронировок в любой момент времени? В настоящий момент каждый раз, когда производится бронирование, независимо от того, сколько пробелов для события требуется (3,4,5 и т. Д.), Counter_cache будет увеличиваться только на единицу. Это создает неточность в количестве заказов по количеству доступных пробелов (и total_amount).

Является ли это так просто, как -

def my_booking 
    event.bookings_count * booking.quantity 
end 

Если да, то где/как я называю это в моем процессе MVC?

Это моя модель бронирования с помощью метода set_booking (для платежей), но должен ли быть метод здесь или в моей модели событий?

class Booking < ActiveRecord::Base 

    belongs_to :event, counter_cache: true 
    belongs_to :user 
    before_create :set_booking_number 


    validates :quantity, presence: true, numericality: { greater_than_or_equal_to: 0 } 
    validates :total_amount, presence: true, numericality: { greater_than_or_equal_to: 0 } 

    validate(:validate_booking) 
    #validate(:validate_availability) 

    def set_booking_number 
    self.booking_number = "MAMA" + '- ' + SecureRandom.hex(4).upcase 
    end 

    def set_booking 

     if self.event.is_free? 
      self.total_amount = 0 
      save! 
     else 
      self.total_amount = event.price_pennies * self.quantity 
      begin 
      charge = Stripe::Charge.create(
       amount: total_amount, 
       currency: "gbp", 
       source: stripe_token, 
       description: "Booking created for amount #{total_amount}") 
      self.stripe_charge_id = charge.id 
      save! 
      rescue Stripe::CardError => e 
      # if this fails stripe_charge_id will be null, but in case of update we just set it to nil again 
      self.stripe_charge_id = nil 
      # we check in validatition if nil 

      end 

     end 


    end 

     def validate_booking 

     # stripe_charge_id must be set for not free events 
     unless self.event.is_free? 
      return !self.stripe_charge_id.nil? 
     end 
     end 



end 

ответ

0

Я думаю, что лучший способ - реализовать свой собственный метод кеширования.

Class Event 
    def update_bookings_count(amount) 
    update_column(:bookings_count, "bookings_count + #{amount}") 
    end 
end 

После бронирования был успешным вызов:

event.update_bookings_count(quantity) 

И просто использовать event.bookings_count, когда требуется подсчет.

Другой вариант, возможно, заключается в том, чтобы изучить этот драгоценный камень: https://github.com/magnusvk/counter_culture#totaling-instead-of-counting, похоже, делает то, что вы хотите.

+0

Вы правы в этом Gem, но что, если я уже реализовал миграцию, чтобы включить counter_cache. Я почти уверен, что это нельзя переоценить. –

+0

Вы можете создать новую миграцию, которая удаляет старый столбец. remove_column: table_name,: column_name – user2959701