在Rails索引视图中,您将迭代集合,并显示集合数据中的每个项目。在大多数情况下,我最终会得到一个复杂的视图,因为需要对集合中的特定项进行额外的计算。这是一个典型的例子:
- if @projects.blank?
= render "shared/placeholder", colspan: "10"
- else
- @hours_total = 0
- @turnover_total = 0
- @projectusers_total = 0
- @projects.each do |project|
- decorate project do |decorates|
- project_calc = ProjectCalculator.new(project)
- hours = project_calc.get_project_data("hours")
- turnover = project_calc.get_project_data("turnover")
- @hours_total += hours
- @turnover_total += turnover
- @projectusers_total += project.projectusers.size
%tr
%td= link_to decorates.data_field(project.name), admin_project_path(project)
%td= decorates.data_field(project.customer.name) unless project.customer.blank?
%td= decorates.data_field(project.company.name_short)
%td= decorates.status
%td= decorates.data_field(project.projectusers.size)
%td= decorates.decimal(hours)
%td= decorates.amount(turnover)
%td= decorates.fixed_price
%td= decorates.show_progress("hours", "compact", hours)
%td= decorates.show_progress("turnover", "compact", turnover)
我已经实现的改进是使用装饰器来查看特定的视图,另一个是使用服务对象进行实际计算。
但是这里困扰我的是所有计算。什么是使这个更简单,理想情况下在视图中没有这个的解决方案?
答案 0 :(得分:1)
使用演示者怎么样?
此链接对我有很大帮助:http://robertomurray.co.uk/blog/2014/decorators-presenters-delegators-rails/
这是另一个简短概述
在您的情况下,您可以像这样实现它
# app/presenter/project_presenter.rb
class ProjectPresenter
attr_accessor :project, :project_calculator
def initialize project
@project = project
@project_calculator = ProjectCalculator.new
end
def hours
project_calculator.get_project_data("hours")
end
def show_progress *args
# calculate progress
end
end
在您的控制器中,您可以为每个项目初始化演示者
@projects = Project.all.collect { |project| ProjectPresenter.new(project) }
因此,您的视图可以使用
访问演示者 - @projects.each do |project|
%tr
%td= project.show_progress('hours')
希望它会有所帮助
ciao boris