Fractal / Tree, how strong parameters?

Is there a way to specify arbitrarily deep strong parameters for tree structures in Rails 4? For example, how can I specify something as follows:

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

So that each node has a name attribute and a node attribute?

+6
source share
3 answers

There may be a cleaner solution to resolve this issue, but this is my current job. The general idea is to calculate how deep my nesting is, and then automatically generate the correct nested hash based on this number. So follow your example:

 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 

(The above example can be cleared more, because it is based on my code, where the top level does not have the same parameters. I left it as I did since it worked on my system.)

+3
source

You can decide, depending on the number of levels that can be more than the levels that you really need, so you can count the appearance of the keys of the recursive keys nodes in the hash and use this count as the number of levels.

Please note that this account will have more levels that you really need, but it’s easier than recursively counting the number of levels in a hash

So, in your controller you can:

 # 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) 

Indeed, strict code for strict parameters may look like this:

 # 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
source

This is not possible with strong parameters. To do this, you should use a simple ruby, that is, convert your parameters to a hash using to_hash and independently check the format.

0
source

Source: https://habr.com/ru/post/949476/


All Articles