rails在创建之前显示计算字段

时间:2015-09-15 13:50:28

标签: ruby-on-rails model wizard actioncontroller

我有一个预算模型,我有一个名为calculate_budget

的方法
class Budget < ActiveRecord::Base

# Assoziations
  belongs_to :member
  belongs_to :donation

# Callbacks
  after_create :calculate_budget, :transfer_old_remaining_promise_to_current_budget

# Public: It is called immediatly after creating (callback) a budget model and it's
#         calculating the budget "promise" (column) based on "donation formula"
#         and income of the member.
#
# Returns:
#         true or false
  def calculate_budget
    ...
    ...
  end

我想向预算创建者(用户)显示在保存之前在控制器/视图中计算的值。在将其保存到promise列之前,用户应该可以对其进行编辑。

我目前正在寻找如何实施流量并提供计算值的想法。

2 个答案:

答案 0 :(得分:4)

根据您所需的用户体验和限制,有多种可能性。这里有3个。

  1. 添加刷新页面的预览按钮。

    该按钮会调用将所有数据添加到Budget的操作,并在不保存Budget的情况下呈现相同的视图。然后,用户可以更改promise值,然后提交表单。

    class BudgetsController < ApplicationController
      def new
        @budget = Budget.new
      end
    
      def create
        @budget = Budget.new(create_params)
        ... # save, redirect and whatever else
      end
    
      def preview
        @budget = Budget.new(create_params)
        # Check validity of the data if calculate_budget does not
        @budget.calculate_budget # Assuming this method does not save the budget
        render :new
      end
    
      ...
    end
    

    使用此控制器,只需将promise字段添加到您的视图中,并在将数据提交到preview操作后填写。

  2. 使用AJAX查询promise

    实现将promise值呈现为纯文本或json的操作,并使用javascript在表单中显示该值。这种方法可以避免页面刷新。

  3. 使用javascript计算

    在javascript中实现promise计算的逻辑,并在用户填写表单时显示它。这通常对用户来说是最好的,但有几个缺点。即您需要复制逻辑,在某些情况下甚至可能无法实现。

答案 1 :(得分:1)

取决于你想要的方式。我会给你一个服务器端的解决方案;如果没有人先跳,我也会做ajax。基本上我们可以劫持熟悉的新 - &gt;方法上的错误 - &gt;再次渲染新流程:

  • 为模型attr_accessor :budget_reviewed
  • 添加“虚拟”布尔属性
  • 让您的预算方法执行validate :budget_review_needed
  • 该方法应该errors :add :budget, 'needs to be reviewed' unless budget_reviewed(语法可能有问题)
  • 要添加实际的budget属性,您需要查找已查看预算的确认。这就是budget_reviewed进来的地方
  • 让用户输入他们的预算数据(例如,这会在控制器的new方法中发生)
  • 他们无法在参数中输入budget_reviewed - 我们会为视图添加该检查
  • 首先调查@budget = Budget.new(budget_params); @budget.save被调用它将失败并显示:budget错误,文字为needs to be reviewed

类似的东西:

def create
  @budget = Budget.new budget_params
  if @budget.save
    redirect_to budgets_path
  else
    render 'new'
  end
end
  • 在您的视图中查找该错误,如果您发现它同时显示计算的预算并在表单中添加一个复选框I have reviewed the budget
  • 如果用户点击该复选框,则该值应通过params进入@budget的属性,并且应该知道预算已经确认。
  • 利润(双关语)

可以说ajax更清晰,但这也是可能的。