如何防止过多的if-else条件

时间:2015-06-23 06:24:57

标签: ruby-on-rails ruby if-statement coding-style

我有控制器来控制用户是否可以租用产品。我有很多条件要检查,每个都有不同的结果。我的if else语句太多了。我想知道我可以遵循哪种设计模式使其更具可读性。

if current_user
  if rental_valid?
    if current_user.approved
      if eligible_to_use?(product_id)
        # redirect_to payment
      else 
        # redirect_to :back
        # alert not eligible
      end 
    else
      # redirect_to verify_path
    end 
  else
    # redirect_to :back
    # alert, rental not valid
  end 
else
  # redirect_to login_path
end

3 个答案:

答案 0 :(得分:5)

假设这是一种方法:

return redirect_to login_path unless current_user
return redirect_to(:back; alert, rental not valid) unless rental_valid?
return redirect_to verify_path unless current_user.approved
return redirect_to(:back; alert not eligible) unless eligible_to_use?(product_id)
return redirect_to payment

如有必要,请将return替换为break等,以匹配环境。

答案 1 :(得分:1)

您的方法有太多if-elses,因为它试图处理太多问题(身份验证,授权,业务逻辑)。重构if-elses的数量将减少代码行,但从长远来看不会提高可维护性。尝试分别理解和管理个人问题。

可以将current_user检查委托给`ApplicationController中的身份验证before_action

current_user.approved看起来像授权问题,应由您的授权解决方案处理,可能是cancancanpundit。 (最简单的是,此控制器中的授权before_action

在处理完这两个之后,可以使用Policy Object处理剩余部分以封装特定于域的逻辑。这将使您的控制器操作看起来类似于以下内容:

policy = ProductRentalPolicy.new(current_user, product) 
if policy.eligible_to_use? && policy.rental_valid?
  redirect_to payment_path
else
  redirect_to :back, error: policy.error
end

答案 2 :(得分:0)

您可以使用filters将常用和可重复使用的重定向移动到方法中。

before_action :user_authorizied, only: [:method_name]
before_action :rental_validability, only: [:method_name]
before_action :user_approved, only: [:method_name]

def method_name
  #...
  if eligible_to_use?(product_id)
    # redirect_to payment
  else 
    # redirect_to :back
    # alert not eligible
  end
end

private

def user_authorizied
  redirect_to(login_path) unless current_user
end

def rental_validability
  redirect_to(:back) unless rental_valid?
end

def user_approved
  redirect_to(verify_path) unless current_user.approved
end