Rails – удаление вычислений из моих представлений?

StackOverflow https://stackoverflow.com//questions/20002550

  •  20-12-2019
  •  | 
  •  

Вопрос

Сейчас я выполняю некоторые вычисления в своих представлениях, что, конечно, плохо:

<% categories.each do |c| %>
  ....
    <%= c.transactions.sum("amount_cents") %>
  ....
<% end %>

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

Одна вещь — перенести расчет на мой контроллер.

@category_sum = @transaction.sum("amount_cents")

Это, вероятно, лучшее решение, но вы знаете.Не идеально.

Поскольку у меня много пользователей, я не понимаю, как перенести логику калькулятора в мою модель.Итак, я думаю, мне, возможно, придется использовать новый класс, создать кучу методов (сумма, среднее и т. д.) и использовать их в представлениях?Я на правильном пути?Буду благодарен за любые советы о том, как реструктурировать мой код, спроектировать и реализовать этот класс.

Это было полезно?

Решение

Одним из способов изоляции логики представления является использование презентаторов.

Ведущий позволяет вам сделать что-то вроде этого:

<% categories.each do |c| %>
  ....
    <% present c do |category| %>
    <%= category.transaction_sum %>
    <% end %>
  ....
<% end %>

Затем у вас есть класс докладчика в app/presenters/category_presenter.rb :

class CategoryPresenter < BasePresenter
  presents :category

  def transaction_sum
    category.transactions.sum("amount_cents")
  end
end

Конечно, его лучше всего использовать, если у вас много методов в этом презентаторе (но как только вы начнете сокращать логику представления, презентаторы заполнятся быстро).

Используемая здесь реализация основана на том, что описано в это про рельскаст.Основная идея состоит в том, чтобы просто иметь #present помощник, который выводит имя класса на основе класса объекта, загружает и инициализирует соответствующий класс презентатора.

Другой популярной альтернативой является использование торговец, в которых используется концепция декоратора, но ведущий — это, по сути, декоратор.

Другие советы

Главный кодовый запах, вы видите, называется Закон Деметера (который, какМногие программированные «законы», вы должны подумать о нем больше похоже на «руководство Демитера»).

Что вы могли бы сделать, это переместить фактический шаг расчета в метод в категории, например.

class Category < ActiveRecord::Base
  def transaction_amount
    transactions.sum("amount_cents")
  end
end

<% categories.each do |c| %>
  ....
    <%= c.transaction_amount %>
  ....
<% end %>
.

Технически говоря, расчет по-прежнему выполняется при рендеринге представления, но логика для , как рассчитывается, что сумма суммированной суммы больше не находится внутри самого вида.Весь вид теперь заботится о том, что он может отправить сообщение transaction_amount к объектам категории.Это также покидает место для вас, чтобы добавить кеш для сумм или для того, чтобы остановить пропустить фактические записи, но вместо этого пропускать статические объекты (которые не являются моделями Activerecord), которые выходят из какого-либо куска кода, который выполняет сумму вболее эффективно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top