Как вы выполняете вычисления на нескольких моделях Rails, и куда должна идти логика? - PullRequest
2 голосов
/ 02 марта 2012

У меня есть модель Invoice в приложении Rails.Счет-фактура has_many Products and Services (две отдельные модели).В представлении счета-фактуры отображаются эти связанные записи.

И продукты, и услуги имеют схожую структуру, то есть элемент, цена, количество.Я могу рассчитать итоговые суммы как price * quantity, а общую стоимость Продуктов - как all.collect { |product| product.price * product.quantity }, то же самое для Услуг.

Что если я теперь хочу рассчитать общую стоимость Продуктов + Услуг по этому Счету?

Как я могу выполнить расчеты для нескольких моделей?И куда должна идти логика вычислений?

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

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

Ответы [ 3 ]

2 голосов
/ 02 марта 2012

Вкратце: используйте модули. Я думаю что-то вроде:

module TotalCalculator
  def sum
     map { |e| e.price * e.quantity }
  end
end

И тогда вы можете:

class Product
  include TotalCalculator
end

Конечно, это всего лишь тривиальный пример, и названия ужасны. Кстати, вы можете получить картину. Я бы поместил всю логику в директорию типа app/logic или в каталог lib. Иногда я называю этот метод модуль как шаблон бизнес-логики , но я не знаю, правильное ли это имя.

2 голосов
/ 02 марта 2012

Просто чтобы проверить:

  • Счет-фактура has_many продуктов и услуг
  • Продукты имеют метод total_cost (или total_price)
  • Сервисы также имеют метод total_cost

и вы спрашиваете, где поставить логику для общей стоимости товаров и услуг счета. Правильно?

В этом случае вы правильно указалие в счете-фактуре:

def total_cost_of_products
  products.collect { |product| product.price * product.quantity }
end

def total_cost_of_services
  services.collect { |services| service.price * service.quantity }
end

def total_price_of_products_and_services
  total_cost_of_products + total_cost_of_services
end

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

0 голосов
/ 02 марта 2012

Можете ли вы не просто создать виртуальный атрибут в вашей модели счета total_cost, а затем вставить туда свой код?

def total_cost 
  cost = #do your calculation here....
  return cost  
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...