ruby 需要具有哈希Map数组的结构

qoefvg9y  于 2022-11-04  发布在  Ruby
关注(0)|答案(3)|浏览(95)

我使用Ruby on Rails 7构建了一个REST API,它通过HTTP PATCH接受有效负载,如下所示:

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

我想在我的控制器中使用强参数验证此响应的结构。
我已经尝试了一堆类似的所以职位,但他们似乎都不适合我。
以下是我目前所尝试的方法:

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]]}

任何关于我做错了什么的建议都将非常感谢。

5sxhfpxr

5sxhfpxr1#

我刚把问题贴出来就找到了解决办法。
有效的解决方案是:

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
ovfsdjhp

ovfsdjhp2#

为什么要坚持只通过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结构实现,这是一个始终开放的选项。
希望你觉得这个建议有帮助。

oxf4rvwz

oxf4rvwz3#

您可以定义方法以确保参数结构如下所示:

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

相关问题