使用一系列值重构条件

时间:2016-07-23 20:47:19

标签: ruby-on-rails ruby if-statement switch-statement refactoring

如何重构这段Ruby on Rails代码呢?

    def select_plan
        unless params[:plan] && (params[:plan] == '1' || params[:plan] == '2' || params[:plan] == '3' || params[:plan] == '4' || params[:plan] == '5' || params[:plan] == '6' || params[:plan] == '7' || params[:plan] == '8')
            flash[:notice] = "Please select a membership plan to register."
            redirect_to root_url
        end
    end

2 个答案:

答案 0 :(得分:3)

我会做这样的事情。

def select_plan
  unless params[:plan].in?('1'..'8')
    flash[:notice] = "Please select a membership plan to register."
    redirect_to root_url
  end
end

或者像 mu太短建议:让Plan成为真实的东西。它可能是一个数据库模型,也可能只是一个小型Ruby类:

# in app/models/plan.rb
require 'set'
class Plan
  VALID_PLANS = Set.new('1'..'8').freeze

  def self.valid_plan?(plan)
    VALID_PLANS.include?(plan)
  end
end

# used like
def select_plan
  unless Plan.valid_plan?(params[:plan])
    flash[:notice] = "Please select a membership plan to register."
    redirect_to root_url
  end
end

答案 1 :(得分:0)

如果计划编号在数据库中并且有Plan模型,那么您可以简单地说:

@plan = Plan.find_by(:id => params[:plan])
if(!@plan)
  flash[:notice] = "Please select a membership plan to register."
  redirect_to root_url
end

现在您可以访问下一个视图的完整计划详细信息,以便向他们显示名称,描述,价格......以及计划的存在仅存储在一个位置(即数据库)。如果您不需要@plan,那么您可以说:

if(!Plan.where(:id => params[:plan]).exists?)
  ...
end

重要的一点是,应该只有一件事知道有效的计划是什么,任何时候你需要了解计划,你只要求一件事,只有那件事。

最终调用select_plan的视图也会使用数据库(而不是文字数字1到8)来获取有效的计划:

<% Plan.order(...).each do |p| %>
  whatever you need to display the plan as an option...
<% end %>

向数据库添加新计划,一切仍然有效。删除/禁用计划,一切仍然有效。您的软件将更容易维护,更少的错误,更容易理解,并且您已经获得了一个新的好习惯,而不是一个坏习惯。