2013-09-22 14 views
59

Sto cercando di seguire Ryan Bates RailsCast #196: Nested model form part 1. Ci sono due apparenti differenze con la versione di Ryans: 1) Sto usando un'impalcatura incorporata e non elegante come lui sta usando, e 2) Sto correndo rotaie 4 (non so davvero quale versione utilizzi Ryans nel suo cast , ma non è 4).Gli attributi nidificati RoR producono duplicati quando si modifica

Quindi, ecco quello che ho fatto

rails new survey2 
cd survey2 
bundle install 
rails generate scaffold survey name:string 
rake db:migrate 
rails generate model question survey_id:integer content:text 
rake db:migrate 

Poi ho aggiunto le associazioni ai modelli in questo modo

class Question < ActiveRecord::Base 
    belongs_to :survey 
end 

e così

class Survey < ActiveRecord::Base 
    has_many :questions 
    accepts_nested_attributes_for :questions 
end 

Poi ho aggiunto la vista parte nidificato

<%= form_for(@survey) do |f| %> 
    <!-- Standard rails 4 view stuff --> 

    <div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 
    <div class="field"> 
    <%= f.fields_for :questions do |builder| %> 
     <div> 
     <%= builder.label :content, "Question" %><br/> 
     <%= builder.text_area :content, :rows => 3 %> 
     </div> 
    <% end %> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

e, infine, il controller in modo che 3 domande sono creati ogni volta che un nuovo sondaggio viene creata un'istanza

class SurveysController < ApplicationController 
    before_action :set_survey, only: [:show, :edit, :update, :destroy] 

    # Standard rails 4 index and show 

    # GET /surveys/new 
    def new 
    @survey = Survey.new 
    3.times { @survey.questions.build } 
    Rails.logger.debug("New method executed") 
    end 

    # GET /surveys/1/edit 
    def edit 
    end 

    # Standard rails 4 create 

    # PATCH/PUT /surveys/1 
    # PATCH/PUT /surveys/1.json 
    def update 
    respond_to do |format| 
     if @survey.update(survey_params) 
     format.html { redirect_to @survey, notice: 'Survey was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: 'edit' } 
     format.json { render json: @survey.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # Standard rails 4 destroy 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_survey 
     @survey = Survey.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def survey_params 
     params.require(:survey).permit(:name, questions_attributes: [:content]) 
    end 
end 

Quindi, la creazione di un nuovo sondaggio con tre domande va bene. Tuttavia, se provo a modificare uno dei sondaggi, vengono mantenute le tre domande originali, mentre ne vengono create altre tre. Così, invece di avere 3 domande per l'indagine curata, ora ho 6. ho aggiunto

Rails.logger.debug("New method executed") 

al nuovo metodo nel controller, e per quanto posso dire, non viene eseguito quando sto facendo un'operazione di modifica. Qualcuno può dirmi cosa sto facendo di sbagliato?

Qualsiasi aiuto è molto apprezzato!

+0

si può aggiungere la modifica e aggiorna le azioni al codice del controller, in modo da poter verificare la presenza di errori di là? – Almaron

+0

Sicuro! Immagino che qualcosa si sia perso sull'altare della brevità. – conciliator

risposta

145

Quindi l'ho capito. Ho dovuto aggiungere :id ai parametri consentiti nel metodo survey_params. Ora appare così:

# Never trust parameters from the scary internet, only allow the white list through. 
def survey_params 
    params.require(:survey).permit(:name, questions_attributes: [:id, :content]) 
end 

che funziona perfettamente. Sono un principiante del RoR, quindi per favore prenda la mia analisi di questo con un pizzico di sale, ma suppongo che i nuovi id siano generati invece di essere passati all'azione di aggiornamento. Spero che questo aiuti qualcun altro là fuori.

+1

Consiglio utile, grazie! (modifica: solo dicendo perché la maggior parte delle persone non risponde alla propria domanda quando la scoprono ..) –

+2

Certo! Mi sono rivolto a SO così tante volte, che è giusto cercare di restituire qualcosa. :) – conciliator

+1

anche un novizio RoR qui. mi hai salvato! Ho trascorso 2 giorni su questi moduli annidati e sto solo cercando di ottenere questa app relativamente semplice lol. – dtc

7

Utilizzo di cocoon gem su Rails 4, stavo ancora ottenendo campi duplicati anche dopo aver aggiunto :id all'elenco consentito durante la modifica. Notato il seguente così

Unpermitted parameters: _destroy 
Unpermitted parameters: _destroy 

Così ho aggiunto il campo :_destroy al model_attributes: campo consentito e le cose funzionavano senza intoppi dopo.

Per esempio ...

def survey_params 
    params.require(:survey).permit(:name, questions_attributes: [:id, :content, :_destroy]) 
end