如何重构一个简单的长案例语句

How to refactor a simple long case statement

所以我为我的 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' 才能使此解决方案起作用。您还需要确保 active_support 包含在您的 Gemfile 中,并且 bundle install