2009-11-07 6 views
5

私はハウスをモデル化したアプリを持っています。ハウスhas_many部屋、部屋has_manyライトとsmall_appliancesなど私はまた、どのようにアプリケーションにアクセスするCalculatorと呼ばれるコントローラがあります。データは、電卓コントローラを使用して家(およびその部屋)に追加されます。次に、app/views/calculator/report.html.erbにあるレポートが生成されます。計算ロジックはどこでRailsアプリケーションに入りますか?

私の質問は、レポートのすべての計算とロジックはどこに行くべきですか?現在、私はcalculator_helperのいくつかのものをすべて見ています。通常、これはモデルに入るでしょうか?しかし、電卓には生成されたモデルがありません。これの基準は何ですか?

ここに電卓コントローラがあります。

class CalculatorController < ApplicationController 
    def index 
    end 

    def save_house 
    @house = House.new(params[:house]) 
    respond_to do |format| 
     if @house.save 
     format.html { render :action => 'add_rooms', :id => @house } 
     format.xml { render :xml => @house, :status => :created, :location => @house } 
     else 
     format.html { render :action => 'index' } 
     format.xml { render :xml => @house.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

    def add_rooms 
    @house = House.find(params[:id]) 
    @rooms = Room.find_by_house_id(@house.id) 

    rescue ActiveRecord::RecordNotFound 
    logger.error("Attempt to access invalid house #{params[:id]}") 
    flash[:notice] = "You must create a house before adding rooms" 
    redirect_to :action => 'index' 
    end 

    def add_room 
    @room = Room.new(params[:room]) 
    @house = @room.house 

    respond_to do |format| 
     if @room.save 
     flash[:notice] = "Room \"#{@room.name}\" was successfully added." 
     format.html { render :action => 'add_rooms' } 
     format.xml { render :xml => @room, :status => :created, :location => @room } 
     else 
     format.html { render :action => 'add_rooms' } 
     format.xml { render :xml => @room.errors, :status => :unprocessable_entity } 
     end 
    end 
    rescue ActiveRecord::RecordNotFound 
    logger.error("Attempt to access invalid house #{params[:id]}") 
    flash[:notice] = "You must create a house before adding a room" 
    redirect_to :action => 'index' 
    end 

    def report 
    flash[:notice] = nil 
    @house = House.find(params[:id]) 
    @rooms = Room.find_by_house_id(@house.id) 
    rescue ActiveRecord::RecordNotFound 
    logger.error("Attempt to access invalid house #{params[:id]}") 
    flash[:notice] = "You must create a house before generating a report" 
    redirect_to :action => 'index' 
    end 
end 
+0

Calculatorクラスを教えてください。 –

+0

私はジェームズの答えが好きです。あなたが自分自身に尋ねるべきもう一つの質問は、なぜあなたがコンベンションを壊しているのか、なぜ電卓のコントローラーがハウスコントローラーのようなものを扱うのかです。私はそれが間違っていると言っているわけではない、私はちょうどそれがいくつかのより多くの考えを入れておく価値があると言っている。 –

+0

良い点、アンディ。ライアン、あなたがコントローラとビューについて心配する前にモデルを手に入れてください。このアプローチを使用すると、すべての計算の正しい場所がHouseモデルであることがわかります。 –

答えて

0

これは、作成しているデータの種類によって異なります。電卓コントローラはどのように見えますか?

独自のクラスを/ libに作成し、モデルで使用することができます。これは、コントローラ/ヘルパーからロジックを分離するのに適しています。あなたがモデルの中にロジックのいくつかを置くことができなかった理由はありますか?

+0

calculator_controllerはデータを保存し、次のページに移動してより多くの情報を入力できるようにします。 モデルは検証を行っていますが、それはそれです。実行されている計算は、主に家および部屋のパラメータに基づく数値計算です。 電卓のモデルを作ってみましたが、ビューから変数にアクセスできません。すべてのグローバル変数を作成する必要がありますか? – Ryan

1

私はRAILS_ROOT/lib /にCalculatorなどのクラスを作成し、そこでコードを記述します。

/lib /のクラスは、アプリのどこでも利用可能です。

また、/ app/models /にルビーオブジェクトを作成することもできます。 ActiveRecord :: Baseから継承する必要がある理由はありません。

+0

私は、ActiveRecordから継承しないapp/modelsでcalculator.rbファイルを作成しました。ただし、コードをそのファイルに移動すると、ビューからアクセスできなくなります。私はそれがローカル変数ですべてを行ったからだと仮定しています。これを解決する最善の方法は何ですか?グローバル変数に変更しようとしましたが、それは役に立たないようです。 – Ryan

+0

メソッドをモデルに入れると、lib /のクラスではなく、そのロジックを基になるデータに結びつけることができます。また、コントローラとビューですでに処理しているモデルのインスタンス上のメソッドを呼び出すことができるため、インスタンス変数に関するこの問題に悩まされていないという利点があります。 Mixin Moduleなどのコードベース内の複数のクラスで使用されている場合や、再利用可能なサイドカープロジェクト/プラグインにリファクタリングしている場合は、lib /にコードを出してください。ロジックがコードベースの一部である場合は、メインコードでそのロジックを保持します。 –

5

これにはいくつかの方法がありますが、ロジックは確かにビューに属していません。明確な階層構造で互いに関連したさまざまなモデルを持っています。あなたの記述を正しく読んでいるならば、階層モデルのトップがハウスモデルです。その場合、私はHouseモデルに適切なメソッドのメソッドを追加します。これは、特定のHouseインスタンスに関連付けられたRoomモデルの計算メソッドへの呼び出しと、関連ラインの下に作成される可能性があります。関連する計算を各レベルで実行できるようにし、ハウスモデルレベルで1つ以上のメソッドを作成することで、計算に対処するきれいで表現力豊かで維持可能な方法を得ることができます。

また、DBによって実行できる計算が確実に行われることもあります。例えば、ルームモデルが単にそれ自身のデータを照会することによって行うことができる計算がある場合、そのような低レベル計算ロジックを呼び出すためにActiveRecordの能力を使用して計算上の負担をDBにプッシュします。詳細についてはAPI docsをご覧ください。

私は、あなたが望むロジックを非常に慎重に見て、それがモデルのどこに属しているか、計算の実際のデータに近いか、そのデータを表すクラス構造内にあるからです具体的には、何らかの理由で計算を永続的に保存する必要がなければ、計算ロジックを処理するためのモデルを作成しません。

1

[OK]をクリックすると、コードが表示されます。私はcalculator_controllerが実際に計算をしていないことを見ることができます、彼らはビューにありますか?

  1. 家や部屋など必要なものがあれば、Webページのユーザーに返す必要がある結果を返すオブジェクトを設定するテストを作成します。
  2. モデルを作成して(モデルで)、そのテストに合格するようにします。
  3. 上記のコントローラーコードを変更して、新しい電卓モデルを使用してください。
  4. コントローラーのテストも変更します。もちろん、これらのテストではビジネスロジックをテストする必要はありません。

    ビジネスロジックはかなり単純であり、唯一このWebアプリの後ろに使用した場合は、アプリ/モデルフォルダにそれを置くことができます。私の前respose

class MyCoolClass 
    def initialize(clues) 
    @other_things = OtherThing.all 
    end 
    def do_cool_thing; end 
    def calculate_coolness 
    @other_things.length 
    end 
end 

は、その後、あなたのコントローラで、あなたのモデル

def index 
    @mcc = MyCoolClass "A clue as to what I want" 
    render 
end 

のインスタンスを作成します次に、あなたのテンプレートで、あなたは

<%=h @mcc.calculate_coolness %> 

それにアクセスすることができます@other_thingsがinstance__variableのあるノートMyCoolClassであり、アクセッサメソッドが定義されていないテンプレートには一般的にアクセスできません。

+0

私は、論理がARモデルを乱雑にし始めると、このようなモデルを構築するのが好きです。 –

関連する問題