1

传统的 Rails 最佳实践旨在减少控制器中的逻辑代码,因为它们设计用于路由而不是执行复杂的任务。

但是,如果您有半复杂的身份验证逻辑,您如何合理地从控制器中提取该逻辑?

在我看来,以下对于任何基本应用程序来说都是相当“标准”的逻辑。虽然逻辑与“路由”直接相关,但似乎我正在将逻辑放入控制器中并且它不是很小......我在这里会矫枉过正吗?

redirect_to ...由于该方法只能在控制器中访问,因此甚至可以轻松地将这个逻辑提取到一个单独的类中吗?

class SessionsController < ApplicationController
  # Login page POSTs here to perform authentication logic
  def create
    user = User.find_by(email: params[:email])
    if user and user.authenticate(params[:password]) # default has_secure_password
      if user.confirmed?
        if user.account.active?
          flash[:notice] = "Successfully logged in"
          redirect_to root_path
        else
          flash[:error] = "This account is no longer active"
          redirect_to inactive_account_path(user.account)
        end
      else
        flash[:alert] = "You are not confirmed yet"
        redirect_to confirmation_path(user.confirmation_token)
      end
    else
      flash[:error] = "Invalid email or password"
      redirect_to login_path
    end
  end
end
4

1 回答 1

1

如果你愿意,你可以将所有这些东西扔进回调或类似的东西中,这样方法会更简单一些,但路由应该或多或少属于控制器。

class SessionsController < ApplicationController
  before_filter :set_user, :check_confirmed

  def create
    if user.account.active?
      flash[:notice] = 'Successfully logged in'
      redirect_to root_path
    else
      flash[:error] = 'This account is no longer active'
      redirect_to inactive_account_path(user.account)
    end
  end

  private

  def set_user
    user = User.find_by(email: params[:email])
    return if user.authenticate(params[:password])
    flash[:error] = 'Invalid email or password'
    redirect_to login_path
  end

  def check_confirmed
    return if user.confirmed?
    flash[:alert] = 'You are not confirmed yet'
    redirect_to confirmation_path(user.confirmation_token)
  end
end

请注意,ApplicationController如果您希望SessionsController自己更精简,可以将回调放入。

请记住,这是会话控制器,用户状态应该在其他地方进行管理。理想情况下,从逻辑上看,您的 create 方法应如下所示:

def create
  user = User.find_by(email: params[:email])
  if user
    flash[:notice] = 'Successfully logged in'
    redirect_to root_path
  else
    flash[:error] = 'Invalid email or password'
    redirect_to login_path
  end
end

并将用户状态回调或类似的东西放在其他地方(ApplicationController或whatevs)。

于 2015-04-15T03:27:32.247 回答