使用子域重构多个if语句以进行用户身份验证

时间:2010-06-07 22:00:40

标签: ruby authentication permissions

我正在构建一个典型的网络应用,一旦用户注册,他们就会通过自己的子域(company.myapp.com)访问应用。 “检查哪些用户(如果有的话)登录”片段开始变得非常毛茸茸,显然需要写好,因为它经常运行,所以我想知道你们如何重新考虑这些东西。

以下是不同的状态:

  1. 用户必须登录,用户不得拥有公司名称,且子域必须为空白
  2. 用户必须登录,用户必须拥有公司名称,公司名称必须与当前子域名匹配
  3. 用户必须登录,用户必须拥有公司名称,公司名称必须与当前子域匹配,并且用户的is_admin布尔值为true
  4. if !session[:user_id].nil?
      @user = User.find(session[:user_id])
      if @user.company.nil? && request.subdomains.first.nil?
        return "state1"
      elsif !@user.company.nil?
        if @user.company.downcase == request.subdomains.first.downcase && !@user.is_admin
          return "state2"
        elsif @user.company.downcase == request.subdomains.first.downcase && @user.is_admin
          return "state3"
        end
      end
    end
    

3 个答案:

答案 0 :(得分:2)

正如安德鲁所说,你需要在你的用户模型中使用这个逻辑。我将更进一步,使每个条件成为保持代码清洁,可理解,可重用并遵循单一责任原则的方法。并且还在用户模型中定义一个返回状态的方法,如下所示。

class User

  def get_state(request)
    return 'state1' if no_company_and_subdomain?(request)
    return 'state2' if has_company_that_match_subdomain?(request)
    return 'state3' if admin_has_company_that_match_subdomain?(request)
  end

  def no_company_and_subdomain?(request)
    company.nil? && request.subdomains.empty?
  end

  def has_company_that_match_subdomain?(request)
    return false if company.nil? || is_admin
    company.downcase == request.subdomains.first.downcase
  end

  def admin_has_company_that_match_subdomain?(request)
    return false if company.nil? || !is_admin
    company.downcase == request.subdomains.first.downcase
  end

end

然后您的控制器代码将变为这样

if !session[:user_id].nil?
  @user = User.find(session[:user_id])
  @user.get_state
end

显然,您可以根据您的要求更明智地重命名方法。

答案 1 :(得分:1)

您是否可以将某些逻辑移至用户模型,而不是将其置于控制器中?这样,您的代码将更干燥,更好地封装。

答案 2 :(得分:1)

查看replace type with polymorphismreplace type with strategy重构模式(在您的情况下,后者似乎更合适)。它可能会简化您的代码,特别是如果您的代码中有多个类似的条件。

Refactoring Ruby是该主题信息的良好来源。