Ruby on rails Rails-从我的视图中移出计算?

Ruby on rails Rails-从我的视图中移出计算?,ruby-on-rails,ruby-on-rails-4,Ruby On Rails,Ruby On Rails 4,目前我正在视图中执行一些计算,这当然是一件坏事: <% categories.each do |c| %> .... <%= c.transactions.sum("amount_cents") %> .... <% end %> 这可能是一个更好的解决方案,但你知道。不完美 由于我有很多用户,我不知道如何将计算器逻辑移动到我的模型中。所以我想我可能需要使用一个新类,创建一组方法(sum、average等),并在视图中使用它们?我走对了吗?对

目前我正在视图中执行一些计算,这当然是一件坏事:

<% categories.each do |c| %>
  ....
    <%= c.transactions.sum("amount_cents") %>
  ....
<% end %>
这可能是一个更好的解决方案,但你知道。不完美


由于我有很多用户,我不知道如何将计算器逻辑移动到我的模型中。所以我想我可能需要使用一个新类,创建一组方法(sum、average等),并在视图中使用它们?我走对了吗?对于如何重组代码、设计和实现此类的建议,我将不胜感激。

隔离视图逻辑的一个方法是使用演示者

演示者允许您执行以下操作:

<% categories.each do |c| %>
  ....
    <% present c do |category| %>
    <%= category.transaction_sum %>
    <% end %>
  ....
<% end %>
当然,如果您在该演示者中有许多方法,则最好使用它(但一旦您开始减少视图逻辑,就可以快速填充演示者)

这里使用的实现依赖于中描述的内容。基本思想就是让一个
#present
助手根据对象类推断类名,加载并初始化适当的presenter类


另一个流行的替代方法是使用,它使用了decorator的概念,但演示者基本上是一个decorator。

您看到的主要代码气味被称为(与许多编程“定律”一样,您应该将其视为“Demeter指南”)

您可以做的是将实际计算步骤移动到类别上的方法中,例如

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

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

从技术上讲,在渲染视图时仍会执行计算,但计算总和的逻辑不再在视图本身中。视图现在所关心的是它可以将消息
交易金额
发送到类别对象。这也为您提供了空间,可以为求和添加缓存,或者停止传递实际记录,而是传递静态对象(不是ActiveRecord模型),这些静态对象来自以更高效的方式执行求和的代码段。

您能创建一个从c对象返回html的帮助器方法吗?然后用.html-safe注入helper的结果?我知道,有个很棒的家伙向我演示了;)我花了几天时间学习,但完全值得!谢谢你的回答。
class CategoryPresenter < BasePresenter
  presents :category

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

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