如何重构简单的长案例陈述

问题描述

因此,我为Sinatra项目创建了一个下拉表单,我希望它预先填充该选项。我能够做到这一点,但是变成了一个大案子声明!任何想法如何重构呢?谢谢!

get '/animes/:id/edit' do 
    if is_logged_in?
    @anime = Anime.find_by_id(params[:id])
    case @anime.rating
    when 1
        @oneselect = "selected"
    when 2
        @twoselect = "selected"
    when 3
        @threeselect = "selected"
    when 4
        @fourselect = "selected"
    when 5
        @fiveselect = "selected"
    when 6
        @sixselect = "selected"
    when 7
        @sevenselect = "selected"
    when 8
        @eightselect = "selected"
    when 9
        @nineselect = "selected"
    when 10
        @tenselect = "selected"
    end
    erb :'animes/edit'
    else
       redirect to '/' 
    end
end 

这是我的.erb视图文件格式!

 <label for="rating">rating:</label>

<select name="rating" id="rating" value="<%=@anime.rating%>">
  <option value="10"<%=@tenselect%>>10 (Masterpiece)</option>
  <option value="9"<%=@nineselect%>>9 (Great)</option>
  <option value="8"<%=@eightselect%>>8 (Very Good)</option>
  <option value="7"<%=@sevenselect%>>7 (Good)</option>
  <option value="6"<%=@sixselect%>>6 (Fine)</option>
  <option value="5"<%=@fiveselect%>>5 (Average)</option>
  <option value="4"<%=@fourselect%>>4 (Bad)</option>
  <option value="3"<%=@threeselect%>>3 (Very Bad)</option>
  <option value="2"<%=@twoselect%>>2 (Horrible)</option>
  <option value="1"<%=@oneselect%>>1 (Appalling)</option>

</select><br>

解决方法

对不起,我对Sinatra一无所知,所以这个答案可能不合常理。

如果我自己看这段代码,我会按照类似的方式进行思考(未经测试,并且我的erb有点生锈):

<label for="rating">Rating:</label>

<%
options = [
  [10,'10 (Masterpiece)'],[9,'9 (Great)'],[8,'8 (Very Good)'],[7,'7 (Good)'],[6,'6 (Fine)'],[5,'5 (Average)'],[4,'4 (Bad)'],[3,'3 (Very Bad)'],[2,'2 (Horrible)'],[1,'1 (Appalling)']
]
%>

<select name="rating" id="rating">
<% options.each do |option| %>
  <option value="<%= option[0].to_s %>"<%= @anime.rating == option[0] ? ' selected' : '' %>><%= option[1] %></option>
<% end %>
</select><br>

,然后删除case语句。

,

有用的对象可能是从数字等级到其字符串表示形式的映射:

@ratings_map = {
  1 => "1 (Appalling)",2 => "2 (Horrible)",3 => "3 (Very Bad)",etc...
}

您不必为每个等级(@ oneselect,@ twoselect等)传递单独的变量,而只需将@anime本身用作所选值。然后,您可以使用options_for_select辅助函数:

<label for="rating">Rating:</label>

<%= options_for_select(@ratings_map.map{|key,value| [value,key]},@anime.rating) %>

关于options_for_select助手的一些有用的文档: https://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_for_select

编辑: 我深表歉意,把头伸到了Rails的土地上。如果您使用的是Sinatra,则必须在Sinatra应用程序的顶部显式require 'active_support'才能使此解决方案生效。您还希望确保在您的Gemfile中包含了active_support,并且bundle install