有没有办法在Rails 4中为树结构指定任意深度强参数?例如,我如何指定如下内容:
{
"node": {
"name": "parent",
"nodes": [
{ "name": "child1", "nodes": []},
{ "name": "child2", "nodes": [
{"name": "grandchild", "nodes": []}
]}
]
}
}
允许每个节点具有name属性和nodes属性?
答案 0 :(得分: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
(上面的例子可以清理得更多,因为它是基于我的代码,其中顶层没有相同的参数。我离开它就像我在它的系统上工作一样。)
答案 1 :(得分:2)
您可以根据允许级别的数量可能超过实际需要的级别来解决,因此您可以计算哈希值中递归键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
答案 2 :(得分:0)
强参数无法做到这一点。你应该使用普通红宝石,即将你的参数转换为to_hash
的哈希并自己验证格式。