Rails 4 – Strong Parameters – Nested Objects

Ho una domanda piuttosto semplice. Ma non ho ancora trovato una soluzione.

Quindi, ecco la stringa JSON che invio al server:

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

Usando il nuovo metodo di permesso, ho:

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

Ciò non genera errori, ma la voce del database creata contiene null invece del valore groundtruth.

Se ho appena impostato:

 params.require(:measurement).permit! 

Tutto viene salvato come previsto, ma ovviamente questo elimina la sicurezza fornita da parametri forti.

Ho trovato soluzioni, come consentire gli array, ma non un singolo esempio che utilizza oggetti nidificati. Questo deve essere ansible in qualche modo, dal momento che dovrebbe essere un caso d’uso piuttosto comune. Quindi, come funziona?

Per quanto strano possa sembrare quando si vogliono permettere attributi nidificati, si specificano gli attributi dell’object nidificato all’interno di un array. Nel tuo caso lo sarebbe

Aggiornamento come suggerito da @RafaelOliveira

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

D’altra parte se vuoi nidificare di più oggetti allora lo avvolgi in un hash … come questo

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

Rails ha in realtà una buona documentazione su questo: http://api.rubyonrails.org/classs/ActionController/Parameters.html#method-i-permit

Per ulteriori chiarimenti, è ansible esaminare l’implementazione dei permit e degli strong_parameters stessi: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247

Ho trovato questo suggerimento utile nel mio caso:

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

Controlla questo link del commento di Xavier su github.

Questo approccio autorizza l’intero parametro params [: measurement] [: groundtruth].

Utilizzando gli attributi delle domande originali:

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

Permettere un object nidificato:

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