Rails 4 - Parameter Kuat - Objek Bersarang


144

Saya punya pertanyaan yang cukup sederhana. Namun sejauh ini belum menemukan solusi.

Jadi inilah string JSON yang saya kirim ke server:

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

Menggunakan metode izin baru, saya punya:

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

Ini tidak menimbulkan kesalahan, tetapi entri basis data yang dibuat mengandung nullbukan nilai groundtruth.

Jika saya hanya mengatur:

params.require(:measurement).permit!

Semuanya bisa diselamatkan seperti yang diharapkan, tapi tentu saja, ini membunuh keamanan yang diberikan oleh parameter kuat.

Saya telah menemukan solusi, cara mengizinkan array, tetapi tidak satu contoh pun menggunakan objek bersarang. Ini pasti mungkin entah bagaimana, karena itu harus menjadi kasus penggunaan yang cukup umum. Jadi, bagaimana cara kerjanya?



1
@vinodadhikary Itu benar ... Saya pikir OP bingung. Aneh kedengarannya ketika Anda ingin mengizinkan atribut bersarang Anda menentukan atribut objek bersarang dalam array. Di sisi lain jika Anda ingin bersarang beberapa objek maka Anda membungkusnya dalam hash ... lihat api.rubyonrails.org/classes/ActionController/… dan github.com/rails/rails/blob/master/actionpack/lib/…
j03w

@ j03w, Terima kasih atas tautan ke sumbernya. Sudah jelas sekarang. Anda harus menambahkan jawaban di sini untuk temuan ini karena saya pikir ini akan membantu banyak orang lain.
vee

Jawaban:


181

Seaneh kedengarannya ketika Anda ingin mengizinkan atribut bersarang Anda menentukan atribut objek bersarang dalam array. Dalam kasus Anda itu akan menjadi

Perbarui seperti yang disarankan oleh @RafaelOliveira

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

Di sisi lain jika Anda ingin bersarang dari banyak objek maka Anda membungkusnya di dalam hash ... seperti ini

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


Rails sebenarnya memiliki dokumentasi yang cukup bagus tentang ini: http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

Untuk klarifikasi lebih lanjut, Anda dapat melihat implementasi permitdan strong_parameterssendiri: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247


5
kedua kasus sama dalam jawaban ini, sebenarnya, hanya saja kurung keriting adalah opsional di sekitar {: groundtruth => [...]}; Ini hash tetapi penerjemah dapat menentukan di mana hash dimulai dan berakhir tanpa kurung keriting eksplisit.
Berbicara

Atribut bersarang atribut tidak memungkinkan atribut bersarang. Atribut bersarang dan attr_accessor tercantum dalam aplikasi saya sebagai "Parameter yang tidak diijinkan". Masih mencari solusi yang aman.
Katarzyna

Dalam hal beberapa objek bersarang, Anda juga harus mengizinkan id agar ini berfungsi. Info lebih lanjut di sini: stackoverflow.com/questions/18308714/…
Fabrice Carrega

1
Ini hanya mengizinkan SATU set atribut bersarang. Ini tidak akan berfungsi dalam kasus satu ke banyak.
AKWF

23

Saya menemukan saran ini berguna dalam kasus saya:

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

Periksa tautan komentar Xavier ini di github.

Pendekatan ini membuat daftar putih seluruh params [: pengukuran] [: groundtruth] objek.

Menggunakan atribut pertanyaan asli:

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

4
Hanya catatan tambahan, Ini masih akan ditampilkan di log sebagai parameter yang tidak diizinkan tetapi model akan menerimanya.
Weston Ganger

5
Tidak yakin dengan Rails 4 tetapi dalam proyek Rails 5 saya, saya harus menelepon permit!untuk masuk daftar putih atau tetap tidak diijinkan setelah mengetuknya. Dalam hal ini akan menjadiparams[:measurement][:groundtruth].permit!
nayiaw

@nayiaw saya juga mendapatkan pesan yang tidak disetujui tetapi menambahkan permit!menimbulkan NoMethodError (undefined method izin kesalahan ini ! ' untuk # <Array: 0x007f80cb71ea00>): `
wuliwong

permit!Metode @wuliwong tidak tersedia di Array. Anda harus memiliki akses ke instance kelas masing-masing untuk memiliki akses permit!(sudah lama jadi saya sudah lupa nama kelas tapi itu seperti ActionController::Parametersberdasarkan halaman ini ).
nayiaw

8

Mengizinkan objek bersarang:

params.permit( {:school => [:id , :name]}, 
               {:student => [:id, 
                            :name, 
                            :address, 
                            :city]},
                {:records => [:marks, :subject]})

0

Jika Rails 5, karena notasi hash baru: params.permit(:name, groundtruth: [:type, coordinates:[]])akan berfungsi dengan baik.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.