2013-11-23 2 views
34

Invio una serie di ID di associazione, ad esempio foo_ids al mio controller. Per consentire un array di valori, io uso:Rails - Parametri resistenti con array vuoti

params.permit(foo_ids: []) 

Ora, il problema è che se io mando un array vuoto di foo_ids, il parametro viene ignorato. Invece di cancellare tutto il foos come dovrebbe fare una matrice vuota, l'associazione è lasciata in pace, perché foo_ids non è permesso.

Questo può essere dovuto al fatto che an empty array is converted to nil in rails e che il valore nullo viene ignorato poiché i parametri forti cercano una matrice di valori scalari, non un singolo valore scalare.

Qualcuno può suggerire un buon modo per risolvere questo? Grazie!

Ulteriori informazioni

In un azione di controllo aggiornamento, ho bisogno di essere in grado di gestire due casi. Devo essere in grado di impostare foo_ids su un array vuoto. Devo anche essere in grado di ignorare foo_ids se voglio semplicemente aggiornare un altro campo. Impostare foo_ids su un array vuoto se nil non funziona per questo secondo caso.

risposta

18

La soluzione temporanea sono sceso a è:

params[:foo_ids] ||= [] if params.has_key?(:foo_ids) 
params.permit(foo_ids: []) 

Qui, foo_ids è impostato su un array vuoto solo se è passato. Se non è passato nella richiesta, viene ignorato.

Sto ancora sperando di trovare una soluzione migliore a questo, poiché questo genere di cose sarà abbastanza comune nel progetto a cui sto lavorando - per favore suggerisci idee migliori se ne hai.

+0

Stavo considerando una patch scimmia before_filter dove vorrei fare qualcosa per risolvere questo per tutte le chiavi che terminano in "_ids" . pensieri? – futbolpal

+1

Funzionerebbe. Avevo alcuni casi in cui dovevo farlo per i parametri nidificati negli hash, quindi potresti volerli gestire anche a seconda del tuo utilizzo. –

28

Questo è abbastanza tardi, ma ho avuto questo problema da solo. Ho risolto includendo sia la versione scalari e la versione matrice nell'istruzione permesso, in questo modo:

params.require(:photo).permit(:tags, tags: []) 

FYI - è ha avere sia nella stessa istruzione permesso - se li si concatenano otterrà buttato fuori per qualche motivo.

EDIT: Ho appena notato che un array vuoto inviato tramite questo metodo verrà trasformato in zero - ora ho un sacco di campi che dovrebbero essere array vuoti che sono nulli. Quindi la soluzione che ho postato in realtà non funziona per me.

EDIT il secondo: Pensiero che avevo già aggiunto questo, ma questo problema è relativo a Rails che esegue deep_munge sugli hash dei parametri. Questo commento spiega come risolverlo: https://stackoverflow.com/a/25428800/130592

0

Ho avuto lo stesso problema di recente, ma nessuna delle risposte qui ha funzionato per me. Questa è la mia soluzione. Se hai javascript che gestisce le richieste HTTP, questo potrebbe funzionare anche per te.

nel vostro lato client:

if (photo.tags.length === 0){ 
    photo.tags = ["null"] 
} 

E sul PhotosController

def photo_params 
    p = params.require(:photo).permit(tags: []) 
    p["tags"].reject! { |tag| tag == "null" } 
    p 
end