我对Rails和后端API开发很新,所以如果我滥用一个概念左右,请原谅。现在,我正在尝试重构代码库周围散布的大量条件错误处理代码,并通过将其作为模块包含在API API控制器中,使用明确的已获救异常列表。这将允许我为每个捕获的异常附加自定义但任意的代码,只要我们使用bang替代方法来处理活动记录方法,并且错误处理代码可以存在于一个地方。到目前为止,对于错误处理模块,我有类似的东西:
# app/lib/error/error_handling.rb
module Error
module ErrorHandling
def self.included(klass)
klass.class_eval do
rescue_from ActiveRecord::RecordNotFound do |e|
respond(:record_not_found, 404, e.to_s)
end
rescue_from ActiveRecord::ActiveRecordError do |e|
respond(e.error, 422, e.to_s)
end
rescue_from ActiveController::ParameterMissing do |e|
response(:unprocessable_entitry, 422, e.to_s)
end
rescue_from ActiveModel::ValidationError do |e|
response(e.error, 422, e.to_s)
end
rescue_from CustomApiError do |e|
respond(e.error, e.status, e.message.to_s)
end
rescue_from CanCan::AccessDenied do
respond(:forbidden, 401, "current user isn't authorized for that")
end
rescue_from StandardError do |e|
respond(:standard_error, 500, e.to_s)
end
end
end
private
def respond(_error, _status, _message)
render "layouts/api/errors", status: _status
end
end
end
layouts/api/errors
是使用jbuilder构建的视图。
在ApiController
我们有:
# app/controllers/api/api_controller.rb
module Api
class ApiController < ApplicationController
include Error::ErrorHandling
attr_reader :active_user
layout "api/application"
before_action :authenticate_by_token!
before_action :set_uuid_header
respond_to :json
protect_from_forgery with: :null_session
skip_before_action :verify_authenticity_token, if: :json_request?
private
...
end
不幸的是,这似乎不起作用。运行测试表明私有方法根本没有加载,被认为是未定义的!
更具体地说,这是发出的错误:
uninitialized constant Error::ErrorHandling::ActiveController
和
undefined local variable or method `active_user' for Api::FooController
其中active_user
是通过名为set_active_user
的方法在实例变量中设置的属性。这显然没有被召唤。
但是正在评估ErrorHandling
模块。怎么会这样?我的名字空间不正确还是什么?
感谢阅读。
答案 0 :(得分:1)
答案分为两部分,因为我认为存在两个不同的问题。
统一常数错误
错误
uninitialized constant Error::ErrorHandling::ActiveController
可以通过更改此
来修复rescue_from ActiveController::ParameterMissing do |e|
response(:unprocessable_entitry, 422, e.to_s)
end
到此:
rescue_from ::ActiveController::ParameterMissing do |e|
response(:unprocessable_entitry, 422, e.to_s)
end
(在::
常量前面添加ActiveController
)
ruby中的常量查找将词法嵌套考虑在内。当您在
中引用Constant时module Error
module ErrorHandling
...
end
end
如果以前未定义常量, ruby将尝试在此命名空间中查找常量。预先::
将告诉ruby忽略常量查找时的嵌套。
未定义的本地方法
错误
undefined local variable or method `active_user' for Api::FooController
引发是因为某些代码在类 active_user
上调用实例方法Api::FooController
,而未定义它。
答案 1 :(得分:0)
我知道这是一个老问题,但是我一直在努力,但是找到了解决方法。解决以下问题:
`undefined local variable or method `active_user' for Api::FooController`
您需要添加扩展名ActiveSupport::Concern
,例如
module Error
module ErrorHandling
extend ActiveSupport::Concern
# rest of your code
end
end