6

家をモデル化するアプリがあります。House has_many Rooms、Room has_many Lights and Small_appliances などです。アプリにアクセスするための Calculator というコントローラーもあります。Calculator コントローラーを使用して、家 (およびその部屋) にデータを追加します。次に、app/views/calculator/report.html.erb にあるレポートが生成されます。

私の質問は、レポートのすべての計算とロジックをどこに置くべきかということです。現在、私はそれをすべてビューに持っており、calculator_helper にいくつかのものがあります。通常、これはモデルに含まれますよね?しかし、Calculator には生成されたモデルがありません。これの基準は何ですか?

これが電卓コントローラです。

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
4

4 に答える 4

5

それにアプローチする方法はいくつかありますが、ロジックは確かにビューに属していません。説明を正しく読んでいれば、さまざまなモデルが明確な階層で相互に関連付けられており、階層の最上位がHouseモデルになっています。その場合、Houseモデルに一連のメソッドの適切なメソッドを追加します。これは、特定のHouseインスタンスに関連付けられたRoomモデルの計算メソッドの呼び出しで構成されている可能性があります。このようにして、関連する計算を各レベルで実行でき、Houseモデルレベルで1つ以上のメソッドを作成することで、計算を処理するためのクリーンで表現力豊かで保守可能な方法を得ることができます。

同様に行うべきことの1つは、DBによって実行できるすべての計算が正しいことを確認することです。たとえば、Roomモデルが独自のデータをクエリするだけで実行できる計算がある場合は、ActiveRecordの機能を使用してその計算負荷をDBにプッシュし、そのような低レベルの計算ロジックを呼び出します。詳細については、 APIドキュメントを確認してください。

私はあなたが望むロジックを非常に注意深く見て、それがおそらくそれが属する場所であり、計算の実際のデータに近く、そのデータを具体的に表すクラス構造内にあるため、モデルにどのようにプッシュできるかを確認します。何らかの理由で計算を永続的に保存する必要がない限り、計算ロジックを処理するためだけにモデルを作成することはありません。

于 2009-11-07T04:18:52.770 に答える
1

さて、投稿されたコードを見ることができます。私は、calculator_controller には実際には計算が含まれていないことがわかります。それらはビューにありますか? このアプローチを試してください:

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

私の以前の応答:

ビジネス ロジックが非常に単純で、この Web アプリの背後でのみ使用される場合は、それを app/models フォルダーに配置できます。

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 は MyCoolClass のinstance__variableであり、通常、アクセサー メソッドが定義されていないとテンプレートにアクセスできないことに注意してください。

于 2009-11-07T05:13:24.353 に答える
1

RAILS_ROOT/lib/ に Calculator などと呼ばれるクラスを作成し、そこにコードを配置します。

/lib/ 内のクラスは、アプリのどこでも使用できるようにロードする必要があります。

/app/models/ にプレーンな Ruby オブジェクトを作成することもできます。それらすべてが ActiveRecord::Base から継承しなければならない理由はありません

于 2009-11-07T04:05:08.313 に答える
0

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

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

于 2009-11-07T03:58:40.650 に答える