2015-08-11 19 views
7

Sto inviando un modulo con 2-4 oggetti contemporaneamente, a seconda di quanti genitori hanno. Mi rendo conto che questo è probabilmente non convenzionale, ma volevo davvero che l'utente fosse in grado di modificare tutti gli oggetti contemporaneamente su un modulo. Sulla mia forma, sto facendo:Rails 4 Params forti con più oggetti e chiavi intere

<%= simple_fields_for "derps[]", derp do |f| %> 

<% end %> 

Poi sto facendo questo nel controller:

def update 
    @derps = [] 
    @rejects = [] 
    derps_params.each do |key, hash| 
    derp = Derp.find(key) 
    derp.assign_attributes(hash) 
    @rejects << derp unless derp.save 
    end 
    if @rejects.empty? 
    redirect_to @parent, flash: {success: 'Derps were successfully updated.'} 
    else 
    @derps = @rejects 
    render :edit 
    end 
end 

permette di dire ci sono due oggetti - i params stanno arrivando attraverso come:

"derps"=>{"1"=>{"attribute"=>"39", "another_attribute"=>"serp", "a_third_attribute"=>"yerp"}, "2"=>{"attribute"=>"30", "another_attribute"=>"49", }} 

Ho avuto questo lavoro in Rails 3 senza parametri forti. Sto passando alle rotaie 4 e sto lottando con il modo di ottenere questo lavoro - continuo a ricevere "i parametri non consentito: 1, 2"

sto assumendo che ho bisogno di fare qualcosa di simile:

def mashes_params 
    params.require(:derps).permit(
    id: [] 

o

def mashes_params 
    params.require(:derps).permit(
    :id, 

qualcosa del genere, ma ho provato in tutti i modi che posso pensare, senza fortuna.

Qualche idea qui?

+0

cosa sono 'mash' in mashes_params? Dovrebbe essere "derps"? –

+0

Sì, grazie! Corretto errore di battitura Quello era il mio vero codice.Stavo usando derps come esempio generico. – gregblass

risposta

1

Modifica finale (si spera):

dovuto ripensare questo da zero. Sono giunto alla conclusione: poiché: id funziona come un jolly, ma non è consentito come chiave dell'hash, perché non sempre le chiavi sono 1-4, quindi posso autorizzarle in modo esplicito, quindi ottenere l'ID da una chiave- valore nell'hash, proprio come avviene nel nesting della forma tradizionale? Ecco come ho finito per risolverlo. Ecco l'implementazione finale che ho a lavorare:

<% i = @parent.derps.index(derp) + 1 %> 
<%= simple_fields_for "derps[#{i}]", derp do |f| %> 
    <%= f.hidden_field :id, value: derp.id %> 
    <%= render "rest_of_the_fields" %> 
<% end %> 

Poi nel controller:

def update 
    @derps = [] 
    @rejects = [] 
    derp_params.each do |key, hash| 
    derp = Derp.find(hash.delete("id")) 
    derp.assign_attributes(hash) 
    @rejects << derp unless derp.save 
    end 
    if @rejects.empty? 
    redirect_to @parent, flash: {success: "Derps updated successfully."} 
    else 
    @derps = @rejects 
    render :edit 
    end 
end 

poi qui ci sono i params forti:

def derp_params 
    p = [:id, :attribute_1, :another_attribute, ...] 
    params.require(:derps).permit(
    "1" => p, "2" => p, "3" => p, "4" => p 
) 
end 

Uff. Spero che questo aiuti qualcuno.

+1

Funziona solo se è possibile garantire di non avere più di 4 record annidati, giusto? Quindi non sembra essere una soluzione generica al problema di fondo. –

4

ho trovato che la riga di comando è immensamente utile per il debug dei parametri forte in Rails 4. Ecco come ho provato il vostro problema nella console:

rails C# From within your project directory, short for 'rails console' 

params = ActionController::Parameters.new({ derps: { 1 => { attribute: 39, another_attribute: "serp" }, 2 => { attribute: 30, another_attribute: 49 } } }) 

params # To make sure that the object looks the same 

permitted = params.require(:derps).permit(1 => [ :attribute, :another_attribute ], 2 => [ :attribute, :another_attribute ]) 

permitted # To see what you'd get back in your controller 

Speriamo che con questo strumento, sarete in grado eseguire il debug di tutto ciò che la mia risposta non ha fornito più facilmente di tentativi ed errori.

+0

Ottimo consiglio per la console! Grazie. – RichardAE

+0

Davvero un ottimo tip man. Grazie! – gregblass

0

La soluzione migliore in assoluto che ho visto è here:

def product_params 
    properties_keys = params[:product].try(:fetch, :properties, {}).keys 
    params.require(:product).permit(:title, :description, properties: properties_keys) 
end 

ho fatto un altro cambiamento per scorrere le chiavi senza nome dato che il mio property_keys hanno chiavi e valori più nidificati:

response_keys = params[:survey][:responses].try(:fetch, :properties, {}).keys 
params.require(:survey).permit(responses: response_keys.map {|rk| [rk => [:question_id, :answer_id, :value]]})