在Rails 3中干,如果没有elsif

时间:2012-10-16 01:05:35

标签: ruby-on-rails ruby-on-rails-3

第二周RoR(没有编程背景)。我有一个问题,我正在做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(控制器秀)

<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>

有人告诉我这应该是一个模型,但我真的不知道如何写它。有什么帮助吗?

3 个答案:

答案 0 :(得分:5)

首先,您应该为Show模型添加一个实例方法,以检索并缓存节目的平均评分。这可以防止对同一数据多次查询数据库:

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

返回Show的相应css类的代码可以进入帮助程序(例如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>

安德烈建议的也是可能的,但对于像你这样的初学者来说可能有点难以理解。这更简单。

答案 1 :(得分:2)

您需要在app目录中创建一个名为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方法并使用多种方法来构建表(建议这样做),而不是让一个方法负责整个事情。它可以帮助您隔离问题。希望这能指出你正确的方向

你还应该在谷歌上搜索“演示者+导演”,你可能会发现更多的文章将进一步帮助你理解这个概念。最后rails有处理复杂视图逻辑的宝石,请查看Draper。 https://github.com/drapergem/draper

答案 2 :(得分:0)

我认为对于某人“RoR上的第二周(没有编程背景)”使用演示者有点超出范围。另外一个人应该尝试并简单地逐步进行,并且只对一级人员感到满意(不使用使用不明白的结构)

我的建议是简单地写一个小助手来决定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>

只要您对这种更简单的方法感到满意并稍微使用它,您就可以回过头来调查其他答案中提供的更高级的解决方案。