Rails:接受具有强参数的二维字符串数组

Rails: Accept 2D array of strings with strong parameters

我们有一个 Rails 控制器获取以下数据:

params = ActionController::Parameters.new({
    "requests": [{
        "params": {
            "facets": ["user.id", "user.type"],
            "facetFilters": [
                ["user.type:Individual"]
            ]
        }
    }, {
        "params": {
            "facets": "user.type"
        }
    }]
})

我们想使用强参数来接受这个数据,但是我还没有看到一个模式可以让我们在 facetFilters 中接受二维数组。我正在修改以下内容:

    params[:requests].each do |request|
      request[:permitted] = true
      request[:params].each do |o|
        if ['facets', 'facetFilters'].include?(o.first)
          begin
            o[:permitted] = true 
          rescue
          end
        end
      end
    end

可以看出并非所有属性都是允许的(允许的属性不会传递给子元素),因为 returns:

[<ActionController::Parameters {"params"=><ActionController::Parameters {"facets"=>["user.id", "user.type"], "facetFilters"=>[["user.type:Individual"]]} permitted: false>, "permitted"=>true} permitted: false>, <ActionController::Parameters {"params"=><ActionController::Parameters {"facets"=>"user.type"} permitted: false>, "permitted"=>true} permitted: false>]

还有很多 permitted: false...

这个目标有可能实现吗?任何指示都会非常有帮助!

我发现完成此操作的最佳方法是将二维数组转换为一维数组,允许一维数组,然后将数组转换回二维。

nested_facet_filters = []
(params[:requests] || []).each_with_index do |r, ridx|
  if r[:params].key?(:facetFilters) && r[:params][:facetFilters].kind_of?(Array) && r[:params][:facetFilters].first.kind_of?(Array)
    # flatten the facet filters into a 1D array because Rails can't permit a 2D array
    nested_facet_filters << ridx
    r[:params][:facetFilters] = r[:params][:facetFilters].flatten
  end
end

permitted = params.permit({
  requests: [
    :query,
    :params => [
      :facets => [],
      :facetFilters => [],
    ]
  ]
}).to_h

# after permitting the params, we need to convert the facetFilters back into a 2D array
if nested_facet_filters.present?
  nested_facet_filters.each do |idx|
    # create map from facet key to array of values
    d = {}
    permitted[:requests][idx][:params][:facetFilters].each do |s|
      split = s.split(':')
      facet = split.first
      value = split[1..-1].join(':')
      if d.key?(facet)
        d[facet] << s
      else
        d[facet] = [s]
      end
    end
    # mutate facetFilters back to 2D array for posting to Algolia
    permitted[:requests][idx][:params][:facetFilters] = d.values
  end
end

在 Rails 问题跟踪器 [thread]...

中,有一个接受二维数组的合并请求已开放六年