112

Tôi có một câu hỏi khá đơn giản. Nhưng đã không tìm thấy một giải pháp cho đến nay.Rails 4 - Tham số mạnh - Đối tượng lồng nhau

Vì vậy, đây là chuỗi JSON tôi gửi đến máy chủ:

{ 
    "name" : "abc", 
    "groundtruth" : { 
    "type" : "Point", 
    "coordinates" : [ 2.4, 6 ] 
    } 
} 

Sử dụng phương pháp giấy phép mới, tôi đã có:

params.require(:measurement).permit(:name, :groundtruth) 

này ném không có lỗi, nhưng sự xâm nhập cơ sở dữ liệu được tạo ra chứa null thay vì giá trị trung gian.

Nếu tôi chỉ cần đặt:

params.require(:measurement).permit! 

Tất cả những gì có được của lưu như mong đợi, nhưng tất nhiên, điều này giết chết sự an toàn được cung cấp bởi các thông số mạnh mẽ.

Tôi đã tìm thấy giải pháp, cách cho phép mảng, chứ không phải một ví dụ đơn lẻ sử dụng các đối tượng lồng nhau. Điều này phải có thể bằng cách nào đó, vì nó phải là một trường hợp sử dụng khá phổ biến. Vì vậy, làm thế nào nó hoạt động?

+0

có một cái nhìn vào này http://stackoverflow.com/questions/14483963/rails-4-0 -strong-parameters-lồng nhau-thuộc tính-với-a-key-rằng-điểm-to-a-băm –

+1

@vinodadhikary Nó đã được chính xác ... Tôi nghĩ rằng OP là nhầm lẫn. Như kỳ lạ khi nó âm thanh khi bạn muốn cho phép các thuộc tính lồng nhau bạn chỉ định các thuộc tính của đối tượng lồng nhau trong mảng. Mặt khác, nếu bạn muốn lồng ghép nhiều đối tượng thì bạn quấn nó bên trong một băm… xem http: //api.rubyonrails.org/classes/ActionController/Parameters.html # method-i-permit và https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247 – j03w

+0

@ j03w , Cảm ơn bạn đã liên kết đến nguồn. Bây giờ đã rõ rồi. Bạn nên thêm một câu trả lời ở đây cho phát hiện này vì tôi nghĩ rằng nó sẽ giúp rất nhiều người khác. – vee

Trả lời

143

Như âm thanh lạ khi bạn muốn cho phép các thuộc tính lồng nhau bạn chỉ định các thuộc tính của đối tượng lồng nhau trong một mảng. Trong trường hợp của bạn nó sẽ là

Cập nhật theo đề nghị của @RafaelOliveira

params.require(:measurement) 
     .permit(:name, :groundtruth => [:type, :coordinates => []]) 

Mặt khác nếu bạn muốn lồng nhau của nhiều đối tượng sau đó bạn quấn nó trong một hash ... như thế này

params.require(:foo).permit(:bar, {:baz => [:x, :y]}) 


Đường ray thực sự có tài liệu khá tốt về điều này: http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

Để biết rõ hơn, bạn có thể nhìn vào việc thực hiện các permitstrong_parameters bản thân: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247

+4

cả hai trường hợp đều giống nhau trong câu trả lời này, trên thực tế, nó chỉ là các dấu ngoặc nhọn là tùy chọn xung quanh {: groundtruth => [...]}; Đó là một băm nhưng trình thông dịch có thể xác định nơi băm bắt đầu và kết thúc mà không có dấu ngoặc nhọn rõ ràng. – speakingcode

+0

Các mảng thuộc tính lồng nhau không cho phép các thuộc tính lồng nhau. Thuộc tính lồng nhau và attr_accessor được liệt kê trong ứng dụng của tôi là "Tham số không được gửi". Vẫn đang tìm giải pháp an toàn. – Katarzyna

+0

Trong trường hợp có nhiều đối tượng lồng nhau, bạn cũng nên cho phép id này hoạt động. Thông tin thêm tại đây: http://stackoverflow.com/questions/18308714/nested-fields-and-strong-parameters –

17

tôi thấy đề nghị này hữu ích trong trường hợp của tôi:

def product_params 
    params.require(:product).permit(:name).tap do |whitelisted| 
     whitelisted[:data] = params[:product][:data] 
    end 
    end 

Kiểm tra này link bình luận Xavier trên github .

Cách tiếp cận này đưa vào danh sách trắng toàn bộ tham số [: measurement] [: groundtruth].

Sử dụng các câu hỏi ban đầu thuộc tính:

def product_params 
    params.require(:measurement).permit(:name, :groundtruth).tap do |whitelisted| 
     whitelisted[:groundtruth] = params[:measurement][:groundtruth] 
    end 
    end 
+4

Chỉ cần một lưu ý phụ, Điều này sẽ vẫn hiển thị trong nhật ký dưới dạng tham số chưa được gửi nhưng mô hình sẽ chấp nhận chúng. –

+4

Không chắc chắn về Rails 4 nhưng trong dự án Rails 5 của tôi, tôi phải gọi 'giấy phép!' Để được đưa vào danh sách trắng hoặc nếu không nó vẫn chưa được nhận sau khi khai thác nó. Trong trường hợp này, nó sẽ là 'params [: measurement] [: groundtruth] .permit!' – nayiaw

2

Cho phép một đối tượng lồng nhau:

params.permit({:school => [:id , :name]}, 
       {:student => [:id, 
          :name, 
          :address, 
          :city]}, 
       {:records => [:marks, :subject]}) 
Các vấn đề liên quan