Rails 从高级视图:对视图和控制器之间的模型值执行计算

Rails from a high-level view: performing calculations on a model value between view and controller

这一定是一个普遍的需求,但我似乎无法以最 ruby​​esque 的方式找到明确的答案。我需要创建一个相当复杂的算法来动态计算 rails 4.1 应用程序中的课程成绩。

具体来说,我有一个模型,"course",每当它的一个实例显示在视图中时,我想动态计算当前成绩(一个十进制值,从许多 course.field 值)并使用 switch/case 将其显示为字母值。我的假设是我可以在控制器中执行此操作(但它似乎足够复杂以保证它自己的 -- 模块?在 C++ 中我会创建一个 class)。同时,由于它是动态创建的,在模型中为它​​创建一个 current_grade 字段似乎是一种错误的形式,所以它不是我可以作为允许的参数之一来回传递的(我知道--可以在参数中传递一个没有在数据库中表示的变量吗?)。

在我最初的研究中,我看到了 hidden_field_tags 和 helper_methods 和 all_helpers 以及模块和全局模块等的建议。在时间压力下,我害怕走上错误的道路。哪种方法更好?或者有好的高级文档供参考?

例如,这是一个视图,我想在其中计算当前成绩,将其与所需成绩进行比较,并相应地显示。

# index.html.erb
<% @courses.each do |course| %>
  <li>
    <%= my_algorithm_to_calculate_curr_grade(many course.fields used to caluculate) 
    <= course.desired_grade ? "set li to <Color: red>" : "set li to <Color: green>" %>   
    <%= course.course_name %>     
    Current Calculation: <%= display_results_of_previous_calculation %>   
    (Goal: <%= course.desired_grade %>)   
    <%= link_to 'Show', course %>   
    <%= link_to 'Edit', edit_course_path(course) %>   
    <%= link_to 'Drop Course Without Penalty', course, method: :delete, data: { confirm: 'Are you sure?' } %>
  </li>        
<% end %>

很难从您的问题中判断 course.fields 是课程的属性还是不同的模型。如果所有字段都是课程属性,我会把它作为课程的实例方法。

class Course < ActiveRecord::Base
  def calculated_grade
    # fun algorithm
  end
end

如果 course.fields 需要从数据库加载,我可能会使用普通的旧 Ruby 对象 (PORO),也许将其称为 CourseGradeCalculator(将其放入 app/models,为什么不呢?这是业务逻辑)

class CourseGradeCalculator
  attr_reader :course, :fields, :grade
  def initialize(course, fields)
    @course = course
    @fields = fields
    @grade = calculate_grade
  end

  private

  def calculate_grade
    # fun algorithm
  end
end

# controller
@course = Course.preload(:fields).find(params[:id]

# view
CourseGradeCalculator.new(@course, @course.fields)