2

Rails 3.2アプリでは、ユーザーが入力するフィールド値が変数である計算に基づいて、いくつかのフィールドにデータを入力したいと思います。ただし、現在のコードでは、計算はデータベースにすでに存在する値に基づいてのみ機能するようです-最初の保存では正しく計算されませんが、レコードに戻って2番目に保存すると正しく計算されます時間。

モデル(トレード)には次の4つのフィールドがあります。

  1. entry_price
  2. exit_price
  3. パーセント結果
  4. ドルの結果

ユーザーはエントリー価格で取引を作成し、後でexit_priceで取引を編集します。exit_priceを入力すると、アプリはpercent_resultとdollar_resultを計算する必要があります。ただし、現時点では、これらの結果フィールドは最初の更新時に正しく入力されていません。これは、フィールドからexit_priceを読み取らないため(ユーザーがフォームに入力した場合)、 DB。

私のコントローラーで何が問題になっていますか?

私のコントローラー:

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がデータベースに保存されています。原則として、各データの表現は1つだけである必要がありますが、ここでは2つです。ヘルパーメソッドは次のようになります

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

同様のメソッドをpercent_resultに定義します。この方法を使用すると、システム内に正規の表現が1つしかないため、すべてのデータに一貫性があることを保証できます。

于 2012-11-08T01:38:34.023 に答える