在我的应用程序用户有充分的访问,应用程序需要通过调查后,帐户确认。调查有两个步骤:
TestResult
)
TestResultsController
,模型:级(在该级别内用户指定他的体验级别;控制器:ExperienceLevelsController
,更新current_user.experience_level
) )业务需求:
当用户回答问题时,它被重定向到redirect_to edit_users_experience_level_path(current_user)
,在那里他设置了他的体验级别(在ExperienceLevelsController
和method update
内部)。如果用户完成了调查,但会放弃完成用户体验,稍后再返回,那么只显示体验级别页面是合乎逻辑的。为此,我准备了以下政策:
class TestResultPolicy < ApplicationPolicy
def new?
return false if passed?
if without_result?
redirect_to edit_users_experience_level_path(current_user)
elsif passed?
active?
end
end
def create?
new?
end
private
def passed?
user.test_results.where(test_result: 'passed').any?
end
def without_result?
user.test_results.last.result.nil?
end
end
这是定义专家政策内部重定向的好方法吗?我知道我可以使用user_not_authorized
,但是我已经在ApplicationController中使用了它,在这里我重定向到identity_unconfirmed_path
或root_path:
class ApplicationController < ActionController::Base
include Pundit
before_action :set_paper_trail_whodunnit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
private
def user_not_authorized
flash[:alert] = 'You are not authorized to perform this action.'
return redirect_to(request.referrer || root_path) unless current_user.northrow_status == 'failed'
redirect_to identity_unconfirmed_path
end
end
因此,我是否应该在专家政策中使用重定向流,还是说这不是一个好做法?
发布于 2021-05-04 14:31:20
嘿--像这样的结构化代码使得很难进行测试并在出现bug时找到它们。在这里应用的一个好的经验法则是关注点的分离,理想的情况是,您的政策应该做到这一点,维持治安。
这里要介绍的一个更理想的东西是值边界,您可以通过值将策略和控制器中的逻辑连接起来。我的意思是,简单地从策略中返回一个值并在控制器中对该值进行操作是一个更好的模式,在本例中是一个简单的true
of false
。
您可以考虑的另一件事是在控制器中引发异常并从它中拯救,以执行重定向(可能需要更仔细地考虑这一点)。
我会怎么做?使用值边界方法。从new?
方法中返回true或false,使用它在控制器中向任意方向前进
编辑:刚刚了解到正确或错误的值不能从策略中返回,但是它会引发Pundit::NotAuthorizedError
,在这种情况下,我们可能只需要避免错误并重定向用户。
https://stackoverflow.com/questions/67385915
复制相似问题