我有控制器来控制用户是否可以租用产品。我有很多条件要检查,每个都有不同的结果。我的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
答案 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
看起来像授权问题,应由您的授权解决方案处理,可能是cancancan
或pundit
。 (最简单的是,此控制器中的授权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