2013-11-23 2 views
34

Ich sende ein Array von Assoziations-IDs, sagen foo_ids zu meinem Controller. Um ein Array von Werten zu ermöglichen, die ich benutze:Schienen - Starke Parameter mit leeren Arrays

params.permit(foo_ids: []) 

Nun, das Problem ist, dass wenn ich ein leeres Array von foo_ids senden, wird der Parameter ignoriert. Anstatt alle foos als leeres Array zu löschen, wird die Verknüpfung nicht ausgeführt, da foo_ids nicht zulässig ist.

Dies kann sein, weil an empty array is converted to nil in rails, und dass Nullwert ignoriert wird, da starke Parameter nach einem Array von skalaren Werten suchen, nicht nach einem einzelnen Skalarwert.

Kann jemand einen guten Weg vorschlagen, um das zu lösen? Vielen Dank!

Zusatzinfo

In einem Update Controller-Aktion muss ich in der Lage sein, zwei Fälle zu behandeln. Ich muss in der Lage sein, foo_ids zu einem leeren Array zu setzen. Ich muss auch foo_ids ignorieren können, wenn ich nur ein anderes Feld aktualisieren möchte. Setzen Sie foo_ids auf ein leeres Array, wenn nil für diesen zweiten Fall nicht funktioniert.

Antwort

18

Die temporäre Lösung, die ich gekommen bin unten zu ist:

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

Hier foo_ids wird auf ein leeres Array nur, wenn übergeben wird. Wenn es in der Anfrage nicht übergeben wird, wird es ignoriert.

Ich hoffe immer noch, eine bessere Lösung dafür zu finden, da diese Art von Sache in dem Projekt, an dem ich arbeite, ziemlich üblich sein wird - bitte schlagen Sie bessere Ideen vor, wenn Sie welche haben.

+0

i erwäge einen Affen-Patch before_filter, wo ich etwas tun, würde dies für alle Schlüssel zu adressieren, die in "_ids" beenden . Gedanken? – futbolpal

+1

Das würde funktionieren. Ich hatte ein paar Fälle, in denen ich dies für in Hashes verschachtelte Params tun musste, so dass Sie diese abhängig von Ihrer Verwendung auch behandeln könnten. –

28

Dies ist ziemlich spät, aber ich hatte gerade dieses Problem selbst. Ich löste es, indem sowohl die skalare Version und Array-Version in der Genehmigung Anweisung, etwa so:

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

FYI - es haben sowohl in der gleichen Erlaubnis Aussage - wenn Sie sie verketten es wird erhalten aus irgendeinem Grund rausgeworfen.

EDIT: Ich habe gerade festgestellt, dass ein leeres Array, das über diese Methode gesendet wird, in Null umgewandelt wird - ich habe jetzt eine Reihe von Feldern, die leere Arrays sein sollten, die null sind. Also funktioniert die Lösung, die ich gepostet habe, nicht wirklich für mich.

BEARBEITEN Sie die zweite: Dachte, ich hatte bereits hinzugefügt, aber dieses Problem hängt damit zusammen, dass Rails Deep_munge auf Params-Hashes durchführt. Dieser Kommentar erklärt, wie man es beheben kann: https://stackoverflow.com/a/25428800/130592

0

Ich hatte vor kurzem das gleiche Problem, aber keine der Antworten funktionierte hier für mich. Das ist meine Lösung. Wenn Sie HTTP-Anfragen mit Javascript bearbeiten, kann dies auch für Sie funktionieren.

In Ihrer Client-Seite:

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

Und auf Photos

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