在某些情况下,我需要验证某些参数的存在。这是一个例子:
在我的用户控制器中,为了执行更新操作,我需要验证这些参数的存在。汽车控制器的交易相同,更新操作也一样,您可以在此处看到重复的主题。参数为additional_info
。
我的基本控制器提供了additional_info_params
,可从请求中提取正确的数据。
这是我到目前为止尝试过的。我创建了一个AR控制器问题并将其包含在控制器中,这是一些代码:
module ClassMethods
def require_additional_info_for(*methods)
binding.pry
return unless methods.include?(action_name)
if additional_info_params.empty?
head 400
end
end
end
我的想法是能够在控制器文件的顶部定义需要这些参数的方法,就像来自rails的before_action
或来自cancan的skip_authorization_check
一样。像这样:
MyController < BaseController
include Concerns::AdditionalInformation
require_additional_info_for :update
def update
...
end
end
但是,上面的代码无法按我的预期工作,主要是因为这会在没有太多关于请求的知识的情况下在请求类上触发(我需要通过action_name
来获取操作名称)。
那我该怎么做?
答案 0 :(得分:2)
是的,可以,但是我建议您使用before_action
回调!
在“抽象”控制器中,像这样注册您的方法:
class SameController < ApplicationController
...
protected
def require_additional_params
render status: :unprocessable_entity if additional_info_params.empty?
end
end
此后,将使用此方法的所有控制器必须扩展SameController
,并运行before_action
并将上述方法传递给所需的动作,例如:
class UserController < SameController
before_action :require_additional_params, only: [:action1, :action2]
end
注意:您可以将require_additional_params
放在模块中并包含在控制器中,也可以只将其放在ApplicationController
答案 1 :(得分:0)
您可能还会考虑在各自的控制器中制作这些常规的强参数。看起来像这样:
def update_params
params.require(:car).permit(:engine, :wheels, :rims).tap do |car_params|
car_params.require(:engine)
end
end
这将需要顶级:car
参数(剥离),并且需要:engine
参数,但允许其他两个参数(:wheels
和:rims
)。如果不存在:engine
,它将引发ActionController::ParameterMissing
(就像缺少:cars
一样)
这是直接从action controller strong params docs(最后一个示例在底部)
有时,我会将它们放入相应控制器上的单独私有方法中,因此也可能会有一个具有不同要求的create_params
方法。与使用自定义方法作为before_action相比,我更喜欢这种方法。