根据计算填充 Rails 字段 [英] Populating Rails Fields Based on Calculation

查看:40
本文介绍了根据计算填充 Rails 字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my Rails 3.2 app, I want to populate some fields based on calculations where the field values users enter are the variables. However, with my current code, the calculation seems to only work based on the values already in the database - it doesn't calculate correctly on the initial save, but it will calculate correctly if I go back in the record and save it a second time.

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

I have these four fields in my model (Trade):

  1. entry_price
  2. exit_price
  3. percent_result
  4. dollar_result

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

The user creates a trade with an entry price, and then later edits the trade with the exit_price. When the exit_price is entered, the app should calculate percent_result and dollar_result. However, right now, these result fields are not populating correctly on the first update - it seems to be because it doesn't read the exit_price from the field (when a user enters it in the form), only once it is saved in the DB.

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

What is going wrong in my controller?

我的控制器:

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 %>

推荐答案

在模型中使用 before_save 过滤器可能会更好地实现这一点.

This would probably be better accomplished with a before_save filter in your model.

添加

before_save :calculate_results

到模型的顶部,然后定义

to the top of your model and then define

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 的厚模型和薄控制器"原则,还可能导致数据一致性问题.

in your model as well. Taking this approach ensures that your results will always be consistent with your values for entry and exit price. Enforcing this in the controller violates the Rails principle of "thick model and thin controller" and may also lead to data consistency issues.

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

An even more consistent way of doing this would be to define dollar_result and percent_result as methods in your model. As your model is now, you have dollar_result stored in the database even though it is a derived value. As a general rule, you should only have one representation of each piece of data whereas here you have two. A helper method might look something like

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

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

You would define a similar method for percent_result. Using this method, you can guarantee that all of your data is consistent because it only has one, canonical representation in the system.

这篇关于根据计算填充 Rails 字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆