2

在我的 Rails 3.2 应用程序中,我想根据用户输入的字段值是变量的计算来填充一些字段。但是,使用我当前的代码,计算似乎只能基于数据库中已有的值 - 它在初始保存时计算不正确,但如果我返回记录并保存它,它将正确计算时间。

我的模型中有这四个字段(贸易):

  1. entry_price
  2. 退出价格
  3. 百分比结果
  4. 美元结果

用户创建一个带有入场价格的交易,然后使用 exit_price 编辑该交易。输入 exit_price 后,应用程序应计算 percent_result 和 Dollar_result。但是,现在,这些结果字段在第一次更新时没有正确填充 - 这似乎是因为它没有从字段中读取 exit_price(当用户在表单中输入它时),只有在它保存在D B。

我的控制器出了什么问题?

我的控制器:

def update
  @trade = Trade.find(params[:id])
  exit_price = params[:trade][:exit_price]

  if !exit_price.blank?
    @trade.percent_result = ((exit_price.to_f - @trade.entry_price)/@trade.entry_price) * 100
    @trade.dollar_result = exit_price.to_f - @trade.entry_price 
  end

  params[:trade][:exit_date] = Date.strptime(params[:trade][:exit_date], '%m/%d/%Y') unless params[:trade][:exit_date].blank?
  params[:trade][:entry_date] = Date.strptime(params[:trade][:entry_date], '%m/%d/%Y') unless params[:trade][:entry_date].blank?
  respond_to do |format|
    if @trade.update_attributes(params[:trade])
      format.html { redirect_to @trade, :flash => {:share =>"Your trade was successfully updated.  Don't forget to share it with your friends, so you can profit together!"} }
      format.json { head :no_content }
    else
      format.html { render action: "edit" }
      format.json { render json: @trade.errors, status: :unprocessable_entity }
    end
  end
end

风景

<%= simple_form_for(@trade, :html=>{:class=> "form-horizontal well"})  do |f| %>  
  <%= f.text_field :entry_price, :class=>"input-small" %>
  <%= f.text_field :exit_price, :class=>"input-small" %>

  <%= submit_tag "Edit Trade" %>
<% end %>
4

1 回答 1

6

使用模型中的 before_save 过滤器可能会更好地完成此操作。

添加

before_save :calculate_results

到模型的顶部,然后定义

def calculate_results
    unless self.exit_price.blank? || self.entry_price.blank?
        self.percent_result = ((self.exit_price - self.entry_price)/self.entry_price) * 100
        self.dollar_result = self.exit_price - self.entry_price 
    end
end

在你的模型中也是如此。采用这种方法可确保您的结果始终与您的入场和出场价格值一致。在控制器中强制执行这一点违反了Rails“厚模型和薄控制器”的原则,也可能导致数据一致性问题。

一种更一致的方法是将 Dollar_result 和 percent_result 定义为模型中的方法。正如您的模型现在一样,您将 Dollar_result 存储在数据库中,即使它是派生值。作为一般规则,您应该只对每条数据有一个表示,而在这里您有两个。辅助方法可能看起来像

def dollar_result
    self.exit_price - self.entry_price unless self.exit_price.blank? || self.entry_price.blank?
end

您将为 percent_result 定义一个类似的方法。使用这种方法,您可以保证所有数据都是一致的,因为它在系统中只有一个规范表示。

于 2012-11-08T01:38:34.023 回答