Rails — приложение для выставления счетов

Я создаю приложение для выставления счетов в Rails, которое имеет следующие модели.

class Company < ActiveRecord::Base
  has_many :clients
  has_many :items

class Client < ActiveRecord::Base
  belongs_to :company

class Invoice < ActiveRecord::Base
  belongs_to :company
  belongs_to :client
  has_many :line_items
  has_many :items, through: :line_items
  accepts_nested_attributes_for :line_items

  after_initialize :set_total

  def set_total 
    total = 0 
    items.to_a.each do |item| 
      total += item.price * item.qty 
    end 
    self.total = total 
  end

class Item < ActiveRecord::Base
  belongs_to :company
  has_many :line_items
  has_many :invoices, through: :line_items

class LineItem < ActiveRecord::Base
  belongs_to :invoice
  belongs_to :item

На данный момент я могу успешно генерировать счета. Проблема заключается в том, что общая сумма счета-фактуры меняется всякий раз, когда я меняю цену товара, которая указана в сгенерированном счете-фактуре.

Что было бы лучшим способом предотвратить это? Как только счет-фактура создан, я не хочу, чтобы к его сумме применялись какие-либо изменения.

Спасибо


person Ali ca    schedule 23.02.2016    source источник
comment
Вы храните total в таблице invoice? Можете ли вы предоставить детали реализации метода set_total.   -  person Dharam Gollapudi    schedule 23.02.2016
comment
@Dharam Общий атрибут хранится в таблице счетов, вот метод def set_total total = 0 items.to_a.each do |item| total += item.price * item.qty end self.total = total end   -  person Ali ca    schedule 23.02.2016


Ответы (2)


Вы можете использовать new_record? метод,

  after_initialize :set_total

  def set_total 
    total = 0 
    items.to_a.each do |item| 
      total += item.price * item.qty 
    end 
    self.total = total if self.new_record?
  end

person Sravan    schedule 23.02.2016

after_initialize вызывается как при инициализации новой записи, так и при извлечении записи из базы данных.

Вы можете использовать before_create вместо after_initialize, чтобы общее значение устанавливалось только один раз перед_созданием и не обновлялось каждый раз при инициализации записи.

Вы также можете упростить метод set_total следующим образом:

def set_total
  self.total = items.inject(0) { |sum, item| sum + (item.price * item.qty) }
end

См. Enumerable#inject для получения дополнительной информации вводить.

person Dharam Gollapudi    schedule 23.02.2016
comment
Привет, @Dharam, я попробовал этот способ, и по какой-то причине сейчас общее количество сохраняется как 0,,, - person Ali ca; 24.02.2016