2012-03-22 3 views
10

Ruby on Railsに関するNoobの質問 - 私の状況の例です:モデルcircleと属性radiusがある場合は、circumferenceの計算はどこですか?これはモデルやコントローラにあるのでしょうか?どのように見えるでしょうか? circumferenceは私のviewsでアクセス可能である必要があります。Rails - 派生属性はどこで計算しますか?

また、circumferenceを私のモデル/データベースの一部である属性にする必要はないと考えてもいいですか?それはユーザー入力radiusから派生できるからです。

答えて

14

派生した属性を計算するロジックは、絶対的にモデルに属します。円周はサークル自体のプロパティであり、Webインターフェイスでの表示方法の心配ではありません。どこからでも周囲にアクセスするために

、単に次のような、クラスにメソッドを定義します。

require 'mathn' 
class Circle < ActiveRecord::Base 
    # assume `radius` column exists in the database 

    def circumference 
    Math::PI * 2 * radius 
    end 
end 

それは円周を計算するためにかなり安い、計算なので、必要に応じて、あなたはそれを計算することができます。それはあなたが複数回実行したくなかった、より複雑な計算を関与何かをした場合は、次のように、あなたはそれをmemoizeできます

def circumference 
    @circumference ||= Math::PI * 2 * radius 
end 
メソッドが呼び出された最初の時間 @circumferenceインスタンス変数を設定します

、その後、後続のすべての呼び出しで最初の計算の結果を返します。もしあなたがそれをしていたならば、半径が正確になるように変更したときに@circumferencenilに設定する必要があります。

+0

私は2番目の仮定で明確にする必要があります。私は 'app/models/circle.rb'で計算する必要があると考えましたが、' circumferential'を単純に使うことができますか?変数(すなわち '@ circumferential'インスタンス変数)を追加するか、またはそれを' circle 'のデータベーステーブルの要素として追加する必要がありますか? – Nick

+1

この 'attr'をテーブルに追加すると、' radius'の変更が確実に 'circum'の再計算を引き起こすための追加コードが必要になります。これは、属性の 'def'がこの答えとは少し異なって扱われることを必要とします。 –

+0

'before_save:recalculate_fields' –

関連する問題