第二周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>
有人告诉我这应该是一个模型,但我真的不知道如何写它。有什么帮助吗?
答案 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>
只要您对这种更简单的方法感到满意并稍微使用它,您就可以回过头来调查其他答案中提供的更高级的解决方案。