2013-07-15 37 views
6

Có cách nào xác định các tham số sâu tùy ý cho cấu trúc cây trong Rails 4 không? Ví dụ: tôi sẽ chỉ định điều gì đó như sau:Đệ quy/Cây như thông số mạnh?

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

Để cho phép mỗi nút có thuộc tính tên và thuộc tính nút?

+1

Bạn đã bao giờ tìm ra điều này chưa? – senfo

Trả lời

0

Điều này là không thể với thông số mạnh. Bạn nên sử dụng đồng bằng ruby ​​cho điều đó, tức là chuyển đổi các thông số của bạn thành một băm với to_hash và xác thực định dạng của chính bạn.

3

Có thể có giải pháp sạch hơn để giải quyết vấn đề này nhưng đây là công việc hiện tại của tôi. Ý tưởng chung là tính mức độ làm tổ sâu của tôi và sau đó tự động tạo ra băm lồng nhau chính xác dựa trên số đó. Vì vậy, để theo gương của bạn:

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 

(Ví dụ trên có thể được làm sạch hơn vì nó dựa trên mã của tôi, nơi cấp cao nhất không có thông số tương tự tôi rời nó như tôi đã có nó vì nó làm việc trên. hệ thống của tôi.)

+0

Cảm ơn. Điều này đã cứu tôi rất nhiều đau đầu. Tôi đã tấn công vấn đề này bằng cách cố gắng mở rộng Tham số mạnh. Tự động xây dựng hash giấy phép là một cách tiếp cận dễ dàng hơn. – rodamn

2

bạn có thể giải quyết bằng cách tùy thuộc vào thực tế là số mức cho phép có thể có nhiều hơn mức bạn thực sự cần, vì vậy bạn có thể đếm sự xuất hiện của các đệ quy chính nodes quan trọng trong việc bạn sử dụng băm và số này là số lượng các cấp.

Lưu ý rằng số lượng này sẽ được nhiều hơn mức bạn thực sự cần, nhưng nó đơn giản hơn đệ quy đếm số lượng cấp trong băm

Vì vậy, trong điều khiển của bạn, bạn có thể như sau:

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

Và có mã xây dựng thông số mạnh thực tế có thể giống như sau

# 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 
Các vấn đề liên quan