2012-08-22 5 views
7

Il docs on parameter wrapping Stato:Perché il wrapping dei parametri Rails non include le cose nascoste dall'URI?

avvolge la parametri hash in un hash nidificato. Ciò consentirà ai client di inviare richieste POST senza dover specificare alcun elemento radice.

Si elides utilmente che hash parametri viene ripiegamento. Il Action Controller overview guide dà questa corsa verso il basso:

Rails raccoglie tutti i parametri inviati insieme alla richiesta nel params hash, siano essi vengono inviati come parte della stringa di query o il corpo palo. [...] L'hash query_parameters contiene i parametri inviati come parte della stringa di query mentre l'hash request_parameters contiene i parametri inviati come parte del corpo del post. L'hash path_parameters contiene i parametri riconosciuti dal routing come parte del percorso che conduce a questo particolare controller e azione.

Il divertimento si verifica quando si utilizzano risorse e percorsi RESTful. Supponiamo che tu abbia un modello A che has_many Bs; B ha quindi una chiave esterna a_id.

POST /as/1/bs con un carico utile vuoto (perché B non ha altri campi). Supponendo che a_id sia attr_accessible, si potrebbe supporre che a_id sia racchiuso in un oggetto b. Vedrai invece:

Processing by BsController#create as HTML 
    Parameters: {"b"=>{}, "a_id" => "1"} 

Non ho avuto così tanta fortuna. Si scopre che ParamsWrapper uses request_parameters e non params, quindi non incluso a_id nel payload POST significa che non viene incartato. Questo è piuttosto confuso, perché lo vedete ancora incluso in params, a causa dell'oscuramento URI, e mi chiedo perché è stato escluso da tutte le cose.

C'è qualche buona ragione per usare request_parameters e non params qui?

posso capire che, da un punto di vista "RIPOSO filosofia", è più puro se si assume che il payload contiene l'intero oggetto, ma ciò significa in sostanza che il a_id nella URI è completamente ignorato, che sembra un pietà.

tl; dr:ParamsWrapper utilizza request_parameters come sorgente parametro, così variabili URI globbed vengono ignorati. È un bug di Rails? I puri sostenitori del REST possono dire di no, ma il pragmatismo suggerisce di sì.

+0

Ciao! Hai capito come aggirare questo problema? – dan

+1

@dan: sfortunatamente non ho lavorato con Rails da alcuni mesi dopo aver postato questa domanda, quindi non ho niente! – Ashe

risposta

0

Per quanto ho capito, la ragione per cui a_id non è inclusa nell'hash per 'b' è che abbiamo bisogno del valore id per verificare prima se il record esiste nel nostro database. In questo modo, possiamo semplicemente rifiutare altri parametri nella richiesta. Come per la ragione per non averlo incluso nell'hash "b": può prevenire incidenti. Prendi questo scenario: supponi che qualcuno stia aggiornando un modulo e passi l'hash completo 'b' come argomento a un oggetto modello. Ora, quando chiamiamo model_object.save, potrebbe salvare il record nel nostro database invece di aggiornare il vecchio record che rappresenterà una minaccia per la sicurezza (può succedere se l'oggetto è stato inizializzato in precedenza). Non uno scenario a prova piena, ma gli incidenti accadono durante la codifica e possono aiutarci a prevenire tali incidenti.

0

dipende dal vostro caso d'uso specifico, ma se si sta utilizzando params forti nel controller, è possibile eseguire una

params[:b][:a_id] = params[:a_id] 
params.require(:b).permit(:a_id) 

o semplicemente saltare il metodo di "richiedere" del tutto:

params.permit(:a_id) 
Problemi correlati