7

有没有办法在 Rails 4 中为树结构指定任意深度的强参数?例如,我将如何指定如下内容:

{
  "node": {
    "name": "parent",
    "nodes": [
      { "name": "child1", "nodes": []},
      { "name": "child2", "nodes": [
        {"name": "grandchild", "nodes": []}
      ]}
    ]
  }
}

让每个节点都有一个名称属性和一个节点属性?

4

3 回答 3

3

可能有一个更清洁的解决方案来解决这个问题,但这是我目前的工作。一般的想法是计算我的嵌套深度,然后根据该数字自动生成正确的嵌套哈希。所以按照你的例子:

def count_levels(node_params)
   if !node_params[:nodes].nil?
    max = 0
    node_params[:node_parameters].each do |child_params|
      count = count_levels(child_params[1])
      max = count if count > max
    end
    return max + 1
  else
    return 0
  end
end

def node_params
  node_attributes_base = [:id, :name]
  nodes = []
  (1..count_levels(params[:node])).each do |val|
    nodes = node_attributes_base + [node_attributes: nodes]
  end
  params.require(:node).permit(:id, :name, node_attributes: nodes)
end

(上面的示例可以进一步清理,因为它基于我的代码,其中顶层没有相同的参数。我保留它,因为它在我的系统上工作。)

于 2013-12-30T07:27:59.680 回答
3

您可以根据允许的级别数可能超过您实际需要的级别数来解决,因此您可以计算哈希中递归键键的出现次数nodes并将此计数用作级别数。

请注意,此计数将超过您实际需要的级别,但它比递归计算哈希中的级别数更简单

因此,在您的控制器中,您可以执行以下操作:

# your_controller.rb
# include RecursiveParametersBuilder
recursive_nodes_attr = build_recursive_params(
  recursive_key: 'nodes',
  parameters: params,
  permitted_attributes: [:name]
)
params.require(:model_name).permit(:name, nodes: recursive_nodes_attr)

并且有实际强参数的构建代码可以像下面这样

# helper module 
module RecursiveParametersBuilder
  # recursive_path = [:post]
  # recursive_key = :comment_attributes
  # recursive_node_permitted_params = [:id, :_destroy, :parameterized_type, :parameterized_id, :name, :value, :is_encrypted, :base_param_id, :parent_param_id]
  #
  def build_recursive_params(recursive_key:, parameters:, permitted_attributes:)
    template = { recursive_key => permitted_attributes }

    nested_permit_list = template.deep_dup
    current_node = nested_permit_list[recursive_key]

    nested_count = parameters.to_s.scan(/#{recursive_key}/).count
    (1..nested_count).each do |i|
      new_element = template.deep_dup
      current_node << new_element
      current_node = new_element[recursive_key]
    end
    nested_permit_list
  end
end
于 2016-04-28T14:54:15.383 回答
0

这对于强参数是不可能的。为此,您应该使用纯红宝石,即将您的参数转换为哈希to_hash并自己验证格式。

于 2013-08-16T13:17:33.593 回答