1

RoRの2週目(プログラミングのバックグラウンドなし)。そして、私は少し問題があります、私はMetacriticタイプのウェブサイトをやっています。そして、どこでも評価があります。0から33=赤34から66=オレンジ67から100=緑に決めました。

インデックス(コントローラー:表示)

 <td><% if show.reviews.count == 0 %>0
    <% elsif show.reviews.average("rating").between?(33, 66) %>
    <table class="orange">
      <tr>
        <td><b><%= number_with_precision(show.reviews.average("rating"), :precision => 0) %></b></td>
     </tr>
    </table>
    <% elsif show.reviews.average("rating").between?(66, 100) %>
    <table class="green">
      <tr>
        <td><%= number_with_precision(show.reviews.average("rating"), :precision => 0) %></td>
      </tr>
    </table>
    <% elsif show.reviews.average("rating").between?(00, 33) %>
    <table class="red">
      <tr>
        <td><%= number_with_precision(show.reviews.average("rating"), :precision => 0) %></td>
      </tr>
    </table>
    <% end %>
  </td>

私の問題は、そのコードを何度も繰り返す必要があるということです。(私はまだ始めたばかりです:show(controller show)

<p>
  Note: <% if @ratings == 0 %>0
  <% elsif @ratings.between?(33, 66) %>
  <table class="orange">
    <tr>
      <td><b><%= number_with_precision(@ratings, :precision => 0) %></b></td>
    </tr>
  </table>
  <% elsif @ratings.between?(66, 100) %>
  <table class="green">
    <tr>
      <td><%= number_with_precision(@ratings, :precision => 0) %></td>
    </tr>
  </table>
  <% elsif @ratings.between?(00, 33) %>
  <table class="red">
    <tr>
      <td><%= number_with_precision(@ratings, :precision => 0) %></td>
    </tr>
  </table>
  <% end %>
</p>

誰かがこれはモデルであるべきだと私に言いましたが、私はそれを書く方法を本当に知りません。何か助けはありますか?

4

3 に答える 3

5

まずShow、番組の平均評価を取得してキャッシュするインスタンス メソッドをモデルに追加する必要があります。これにより、同じデータに対してデータベースに複数回クエリを実行することが防止されます。

def average_rating
  @average_rating ||= self.reviews.average('rating')
end

a の適切な css クラスを返すコードはShow、ヘルパー (例ShowHelper: )に入ることができます。

module ShowHelper
  def average_rating_class_for(show)
    if show.average_rating < 34
      'red'
    elsif show.average_rating > 66
      'green'
    else
      'orange'
    end
  end
end

これにより、ビューがよりきれいになります。

<td>
<% if show.reviews.count == 0 %>
  0
<% else %>
  <table class="<%= average_rating_class_for(show) %>">
    <tr>
      <td><%= number_with_precision(show.average_rating, :precision => 0) %></td>
    </tr>
  </table>
<% end %>
</td>

と:

<p>
  Note:
<% if @show.reviews.count == 0 %>
  0
<% else %>
  <table class="<%= average_rating_class_for(@show) %>">
    <tr>
      <td><%= number_with_precision(@show.average_rating, :precision => 0) %></td>
    </tr>
  </table>
<% end %>
</p>

テーブル全体の世代をモデルに移動することもできます。(ここでテーブルを使用するべきではありませんが、それは別の問題です。)

module ShowHelper
  def average_rating_class_for(show)
    if show.average_rating < 34
      'red'
    elsif show.average_rating > 66
      'green'
    else
      'orange'
    end
  end

  def average_rating_table_for(show)
    if show.reviews.count == 0
      '0'
    else
      content_tag :table do
        content_tag :tr do
          contect_tag :td, :class => average_rating_class_for(show) do
            number_with_precision(show.average_rating, :precision => 0)
          end
        end
      end
    end
  end
end

これにより、次のように表示されます。

<td>
  <%= average_rating_table_for(show) %>
</td>

アンドレが提案することも可能ですが、あなたのような初心者には理解するのが少し難しいかもしれません. これは簡単です。

于 2012-10-16T04:54:03.437 に答える
2

アプリ ディレクトリに、presenters という新しいフォルダーを作成する必要があります。次に、rating_presenter.rb というファイルを作成します。

これがプレゼンター ファイルになります。

class RatingPresenter
  def initialize(rating, template)
    @rating = rating
    @template = template
  end

  def get_ratings
     # here you will house the logic to display your tables as needed
     # I would probably determine the output to return the class to set the table accordingly
     # keep in mind that view helpers are available
     # ie.  h.link_to or h.form_tag
  end

  private
    def h # we don't want to be saying @template.link_to etc everywhere, so this is a shortcut
      @template 
    end
end

そして、application_helper.rb ファイルで、クラスを提示するためにクラスを決定する必要があります

def present(object, klass = nil)
  klass ||= "#{object.class}Presenter".constantize # assign object or nil
  presenter = klass.new(object, self)  # assign presenter to object instance
  yield presenter if block_given?  # yield if block is given
  presenter # return presenter
end

したがって、あなたの見解では、ヘルパーメソッドを呼び出します

<% present @rating do |rating_presenter| %>
  <p>
    <%= rating_presenter.get_ratings %>
  </p>
<% end %>

したがって、これは私が学んだいくつかのリソースからの簡単で汚い例です。ニーズに合うようにするには、少し試したり、壊したりする必要があります。メソッドを拡張し、get_ratings複数のメソッドを使用してテーブルを作成できます (これをお勧めします)。1 つのメソッドですべてを処理する必要はありません。問題を切り分けるのに役立ちます。これがあなたを正しい方向に向けることを願っています

また、Google で「presenters +rails」を検索する必要があります。この概念を理解するのに役立つ記事が他にもいくつかあるかもしれません。最後に、Rails には複雑なビュー ロジックを処理するための gem があります。Draper を確認してください。 https://github.com/drapergem/draper

于 2012-10-16T04:40:31.313 に答える
0

プレゼンターを使用する「RoR の第 2 週 (プログラミングのバックグラウンドなし)」は少し範囲外だと思います。また、段階的に単純化して、自分が慣れているレベルまで試してください(理解していない構造を使用しても意味がありません)。

私のアドバイスは、div の色を決定する小さなヘルパーを単純に作成することです。最初のショットとして、次のメソッドを app/helpers/application_helper.rb に入れるだけです。

def color_for_rating(rating)
  if show.average_rating < 34
    'red'
  elsif show.average_rating > 66
    'green'
  else
    'orange'
  end
end

次に、ヘルパーを使用してテーブルクラスに正しい色を与えることにより、次のようにインデックスビューをクリーンアップできます

 <td><% if show.reviews.count == 0 %>0
    <% else %>
    <table class="<%= color_for_rating(show.reviews.average("rating")) %>" >
      <tr>
        <td><b><%= number_with_precision(show.reviews.average("rating"), :precision => 0) %></b></td>
     </tr>
    </table>
    <% end %>
  </td>

このより簡単なアプローチに慣れ、少し使用したらすぐに、他の回答で提供されているより高度なソリューションを調査するために戻って確認できます。

于 2012-10-16T09:29:55.703 に答える