需要具有哈希映射数组的结构



我正在使用RubyonRails7构建一个REST API,该API通过HTTP PATCH接受有效负载,如下所示:

{
"answers": [
{"question_id": 1, "content": "My answer content ONE"},
{"question_id": 2, "content": "My answer content TWO"}
]
}

我想在我的控制器中使用强参数来验证这个响应的结构。

我试过很多类似的SO帖子,但似乎都不适合我。

以下是我迄今为止所尝试的:

params = ActionController::Parameters.new(answers: [{question_id: 1, content: 'some answer'}])
params.require(answers: [:question_id, :content])
# I get: `require': param is missing or the value is empty: {:answers=>[:question_id, :content]} (ActionController::ParameterMissing) 
params.require(:answers).require([:question_id, :content])
# I get: NoMethodError on the second .require
params.require(answers: [[:question_id, :content]])
# I get: param is missing or the value is empty: {:answers=>[[:question_id, :content]]}

如果能指出我做错了什么,我们将不胜感激。

我刚发布问题就找到了解决方案。

有效的解决方案是:

def answer_params
params.require(:answer).each do |answer_param|
answer_param.require(%i[question_id, answer])
end
end

这使我能够确保以正确的结构提供所有值,并在我的控制器方法中使用它,如下所示:

def update
answer_params.each do |answer_param|
puts answer_param['question_id']
puts answer_param['answer']
end
end

为什么坚持只通过ActionController::Parameters验证参数?我总是发现params API对嵌套结构(我为API构建了更深入的结构(的限制,就像你一样,在这种情况下,我总是以最基本的方式验证数据。例如,对于您显示的数据结构,我将以以下方式进行验证:

def validate_answers_data
received_answers_arr = params[:answers]
if received_answers_arr.blank?
# return error requires answers not received
return
end
whitelisted_answers_data = []
received_answers_arr.each do |h|
question_id = h[:question_id]
answer_content = h[:content]
if question_id.present? && answer_content.present?
whitelisted_answers_data << { question_id: question_id, content: answer_content }
end
end
if whitelisted_answers_data.blank?
# return error answers data received found invalid
return
end

whitelisted_answers_data
end

Params API对白名单数据肯定很有用,但当它对特定的数据结构造成限制时,与其坚持只通过API实现验证,不如通过纯Ruby构造实现,这是一个始终开放的选项。

希望你觉得这个建议有用。

您可以定义方法来确保params结构如下:

def answer_params
params.permit(answers: %i[question_id content])
end

然后在update操作中使用此方法,如:

def update
answer_params[:answers].each do |answer_param|
puts answer_param['question_id']
puts answer_param['answer']
end
end

相关内容

  • 没有找到相关文章

最新更新