0

コピーして貼り付けたくないだけです。もっと良い方法があるはずです。

単一のモデルを使用していくつかのデータを 2 つの配列に収集する単一のコントローラーがあります。次に、これらの配列をグラフで使用する単一のビュー (index.html.erb) を作成します。それはとてつもなく単純です。これが全景です。コントローラーからの配列は、明らかに @buildStepArrays と @buildDates です。

<% chart = GChart.line(:title=>"Build Times", :size=>"1000x300", :data=>@buildStepArrays, :colors=>@colors, :legend=>@buildDates) %>
<% chart.axis(:left) %>
<%= image_tag chart.to_url %>

コントローラーはこちら

def index
    # These three arrays should be the same size
    @buildStepArrays = []
    @buildDates = []
    @totalBuildTimes = []  

    @latestId = Env2.last().BuildId
    @latestId = @latestId - 1

    for buildNumber in (@latestId-4)..@latestId
        @build = Env2.find_all_by_BuildId(buildNumber)
        totalTime = 0
        @currentBuildTimes = []
        for step in @build
            @currentBuildTimes << step.Minutes
            totalTime += step.Minutes.to_i
        end
        @buildStepArrays << @currentBuildTimes.map { |e| e.nil? ? 0 : e }
        @totalBuildTimes << totalTime
        @buildDates << @build.last().Created
        @colors = [["FF1300"], ["FF8C00"], ["FFFF00"], ["00CC00"], ["1240AB"]]
    end
end

私がやりたいのは、 1 つだけでなく 4 つのモデル (4 つの異なるデータベースの同じテーブル) からまったく同じデータを収集し、ビューに 1 つではなく 4 つのグラフを表示することです。これを正しく行う方法を知るには、Rails について十分な知識がありません。今の私の唯一のアイデアは、コントローラー内のコードを文字通りコピーして 4 回貼り付け、変数名を変更することです。それはまったくひどいことです。私はどうしたらいいですか?

4

3 に答える 3

0

これを試して

コントローラ

def index
  @data = [Env1, Env2, Env3].map do |model|
    data = Hash.new
    data[:title] = "Build Times"
    data[:buildStepArrays] = []
    data[:buildDates] = []
    data[:totalBuildTimes] = []  

    data[:latestId] = model.last().BuildId
    data[:latestId] = data[:latestId] - 1

    for buildNumber in (data[:latestId]-4)..data[:latestId]
      data[:build] = model.find_all_by_BuildId(buildNumber)
      totalTime = 0
      data[:currentBuildTimes] = []
      for step in data[:build]
        data[:currentBuildTimes] << step.Minutes
        totalTime += step.Minutes.to_i
      end
      data[:buildStepArrays] << data[:currentBuildTimes].map { |e| e.nil? ? 0 : e }
      data[:totalBuildTimes] << totalTime
      data[:buildDates] << data[:build].last().Created
      data[:colors] = [["FF1300"], ["FF8C00"], ["FFFF00"], ["00CC00"], ["1240AB"]]
    end
  end
end

意見

<% @data.each do |data| %>
  <% chart = GChart.line(:title=>data[:title], :size=>"1000x300", :data=>data[:buildStepArrays], :colors=>data[:colors], :legend=>data[:buildDates]) %>
  <% chart.axis(:left) %>
  <%= image_tag chart.to_url %>
<% end %>

すべてをハッシュに入れましたが、ビューにレンダリングする必要がある場所に配置する方がよいでしょう。

于 2012-08-27T23:23:06.873 に答える
0

最も洗練された解決策は、おそらくプレゼンターを使用することです。プレゼンターは、ビューからロジックをクリーンアップするか、コントローラーからあまりにも多くのインスタンス変数をクリーンアップするのに役立ちます。ここでは後者のようです。

プレゼンターを使用すると、次のことが可能になります。

  • あなたの場合、4つのデータベースすべてから単一のクエリを実行して、データベースクエリを最適化します。
  • プレゼンターのアクションに直接テストを記述できるようにすることで、コードのテストがはるかに簡単になります。

アプリの詳細を知らずにプレゼンターを作成する方法を正確に説明することは困難ですが、モックアップ コードを使用した一般的なガイドラインを示して、そのしくみを説明することはできます。

4 つの異なるモデルからインスタンス変数を単純に定義する代わりに、コントローラーで次のような新しいアクションを定義します。

/app/controllers/charts_controller.rb

...
def show
    @data = ChartPresenter.new(argument)
end
...

次に、ビューで必要な出力に対応するアクションを使用して、新しいプレゼンター クラスを新しいディレクトリに定義します。

/app/presenters/chart_presenter.rb

class ChartPresenter

    def initialize(data)
        @data = data
    end

    def method_name
        ...
    end

end

/app/views/chart.html.erb

...
<%= @data.method_name %>
...

参考文献

PS

ほとんどのチュートリアルでは、プレゼンターのディレクトリconfig/application.rbに設定するように編集するように指示されます。config.autoload_pathsただし、Rails 3 では、以下のすべてが自動的に追加されるため、これは不要になりました。/app/*

于 2012-08-28T00:18:40.990 に答える
0

これを達成する1つの方法は、繰り返されるコードを保持するモジュールを作成することです。これは、少なくとも4回です。あなたがすることは、各モデルのコントローラーファイルを作成することです...

class ModelAController < ApplicationController
  include BasicActions
  before_filter get_model      

  def get_model
    @model = self.class.to_s.gsub("Controller").classify
  end
end

「get_model」メソッドは重要です。これは、@model 変数を設定して、扱っているクラスを保持するためです。コース名のテキストだけを取得するための正確なコードを確認していないので、それをいじる必要があります。おそらくモジュール内で @model を使用するでしょう。

ここに骨格モジュールがあります:

module BasicActions

  def some_method
    ...
  end

レンダリングするアクションごとに関連するすべてのビューが必要ですが、ビューのセットを 1 つだけに制限する方法があります...

于 2012-08-27T23:58:41.647 に答える