2012-11-07 96 views
1

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

  • percent_result
  • dollar_result
  • 用户以入门级价格创建一个贸易

    1. entry_price
    2. exit_price:

      我在我的模型(贸易)有这四个领域,然后稍后用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 %> 
      

    回答

    5

    这很可能会在你的模型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定义类似的方法。使用这种方法,您可以保证所有的数据都是一致的,因为它在系统中只有一个规范的表示。