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?

Benjamin M
sumber
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

j03w
sumber
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
M.ElSaka
sumber
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]})
Codiee
sumber
0

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

pengguna8164115
sumber