Rotaie 4 - Parametri forti - Oggetti nidificati


144

Ho una domanda piuttosto semplice. Ma finora non ho 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)

Questo non genera errori, ma la voce del database creata contiene nullinvece il valore groundtruth.

Se ho appena impostato:

params.require(:measurement).permit!

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

Ho trovato soluzioni, come consentire le matrici, ma non un singolo esempio usando oggetti nidificati. Questo deve essere possibile in qualche modo, dal momento che dovrebbe essere un caso d'uso piuttosto comune. Quindi, come funziona?



1
@vinodadhikary Era corretto ... Penso che l'OP sia confuso. Per quanto strano possa sembrare quando si desidera consentire gli attributi nidificati, si specificano gli attributi dell'oggetto nidificato all'interno dell'array. D'altra parte, se vuoi annidare più oggetti, poi avvolgilo in un hash ... vedi api.rubyonrails.org/classes/ActionController/… e github.com/rails/rails/blob/master/actionpack/lib/…
j03w,

@ j03w, grazie per il link alla fonte. Adesso è chiaro. Dovresti aggiungere una risposta qui per questa scoperta poiché penso che aiuterà molte altre persone.
v.

Risposte:


181

Per quanto strano possa sembrare quando si desidera consentire gli attributi nidificati, si specificano gli attributi dell'oggetto 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 più oggetti, lo avvolgi in un hash ... come questo

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


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

Per ulteriori chiarimenti, è possibile esaminare l'implementazione di permite strong_parametersse stesso: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247


5
entrambi i casi sono gli stessi in questa risposta, in realtà è solo che le parentesi graffe sono opzionali intorno a {: groundtruth => [...]}; È un hash ma l'interprete è in grado di determinare dove inizia e finisce l'hash senza parentesi graffe esplicite.
speakingcode

Le matrici di attributi nidificate non consentono attributi nidificati. Gli attributi nidificati e attr_accessor sono elencati nella mia applicazione come "Parametri non consentiti". Sto ancora cercando una soluzione sicura.
Katarzyna,

In caso di più oggetti nidificati, dovresti anche consentire l'id per farlo funzionare. Maggiori informazioni qui: stackoverflow.com/questions/18308714/…
Fabrice Carrega,

1
Ciò consente solo UN set di attributi nidificati. Questo non funzionerà nel caso di uno a molti.
AKWF

23

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 oggetto params [: misura] [: 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

4
Solo una nota a margine, questo verrà comunque mostrato nel registro come parametri non consentiti, ma il modello li accetterà comunque.
Weston Ganger,

5
Non sono sicuro di Rails 4 ma nel mio progetto Rails 5 devo chiamare permit!per essere inserito nella whitelist, altrimenti è rimasto non ammesso dopo averlo toccato. In questo caso sarebbeparams[:measurement][:groundtruth].permit!
nayiaw il

@nayiaw ricevo anche il messaggio non autorizzato ma l'aggiunta permit!aumenta questo NoMethodError (undefined method permesso di errore ! ' per # <Matrice: 0x007f80cb71ea00>): `
wuliwong

Il permit!metodo @wuliwong non è disponibile in Array. Dovrai avere accesso alla rispettiva istanza della classe per avere accesso permit!(è passato un po 'quindi ho dimenticato il nome della classe ma è qualcosa di simile ActionController::Parametersbasato su questa pagina ).
nayiaw,

8

Autorizzazione di un oggetto nidificato:

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

0

Se è Rails 5, a causa della nuova notazione hash: params.permit(:name, groundtruth: [:type, coordinates:[]])funzionerà bene.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.