2010-10-19 18 views
1

J'essaie d'enregistrer beaucoup nouveaux objets sous une forme à préexistant objet parent.Quelqu'un sait comment enregistrer de nombreux objets dans un formulaire?

- form_for :parent_object do |f| 

Ceci est le début de mon formulaire. Et puis à l'intérieur, je le ferais:

- 2.times do 
    - fields_for :child_object do |f| 

Maintenant, si je devais sauver cela, il viderait comme ParentObject_Controller l'action de mise à jour qui échouera parce que mise à jour ne permet pas d'identifier de nouveaux objets.

Donc, si je voulais rendre l'action appropriée Enregistrer, je dois mettre en place comme ceci:

- form_for [@parent_object, @child_object] do |f| 
    - 2.times do 
    - fields_for :child_object do |f| 

Cette forme rend alors l'action Enregistrer, mais seulement enregistre le dernier child_object.

Je voudrais vous montrer mon contrôleur, mais il n'y a guère de point parce que c'est dévastateur erroné.

Ma question est, comment voulez-vous sauver beaucoup de nouveaux objets sous une forme à un objet parent préexistante?

J'ai beaucoup étudié le travail de Ryan Bate, et beaucoup d'autres blogs et autres publications à ce sujet. Rien ne semble vraiment pointer vers la création spécifique de nouveaux objets enfants pour un objet parent préexistant.

Mise à jour:

Je suis sous l'impression que je dois passer les actions de contrôleur de parent_object pour def update.

elsif params[:parent_object][:child_object] 
    @child_object = Child_Object.new(params[:child_object]) 
    if @child_object.valid? && @parent_object.referrals << @child_object 
     redirect_to new_parent_object_child_object_path(@parent_object) 
    else 
     render :action => :new 
    end 

Débogueur, si je je place un débogueur à la racine de def update, et j'écris:

>> params[:parent_object] 
#=> nil 

Intéressant! Cela signifie que quand child_object est envoyé au contrôleur parent_object, les params ne sont pas remplis pour cela. Haha, aucune idée de ce qu'il faut faire à ce sujet ..

Malheureusement, ce code ne fonctionne pas, c'était juste ma tentative de se rapprocher. ;)

Répondre

0

Vous pouvez jeter un oeil à this answer J'ai donné à une question similaire. Il y a deux options: avec des formulaires séparés, ou avec un seul formulaire.

Il vous suffira de changer le moderate_names_path pour le chemin correct vers votre instance de modèle parent (et bien sûr l'ensemble des champs que vous souhaitez modifier). Vous pouvez le faire avec polymorphic_path:

polymorphic_path([@parent_object, @child_object]) 
+0

J'ai déjà une URL explicite pour cela. '--form_for [@parent_object, @child_object: url => parent_object_child_object_path fait | f |' Pourquoi créer un chemin polymorphe? Vous dites que cela permet la possibilité d'enregistrer plusieurs objets dans un formulaire? – Trip

+0

Hmm .. Si je devais créer une définition personnalisée pour parent_object, qu'est-ce que cela inclurait? Merci pour votre aide, j'ai été bloqué sur cela pendant des jours. : D – Trip

+0

Eh bien, peut-être que ces exemples ne sont pas exactement ce dont vous avez besoin. Quels screencasts RB avez-vous essayé? Celui-ci: [Nested Model Form] (http://railscasts.com/episodes/196-nested-model-form-part-1)? Il semble décrire exactement ce que vous voulez. – Matt

1

OK, nous allons donner un autre coup.Code prise de RB's screencast avec les noms d'objets remplacés:

<% form_for @parent_object do |f| %> 
    <%= f.error_messages %> 
    <!-- some field of parent object here --> 
    <p> 
    <%= f.label :name %><br /> 
    <%= f.text_field :name %> 
    </p> 
    <% f.fields_for :child_objects do |builder| %> 
    <!-- some fields for child objects --> 
    <p> 
    <%= builder.label :content, "Some content for child object" %><br /> 
    <%= builder.text_area :content, :rows => 3 %> 
    <%= builder.check_box :_destroy %> 
    <%= builder.label :_destroy, "Remove child object" %> 
    </p> 
    <% end %> 
    <p><%= f.submit "Submit" %></p> 
<% end %> 

C'est une forme de @parent_object qui a des champs pour :child_objects. Bien sûr, vous devez remplacer les champs par les vôtres.

Pour faire ce travail, vous devrez construire des objets de l'enfant dans le constructeur:

def new 
    @parent_object = ParentObject.new 
    3.times { @parent_object.child_objects.build } 
end 

De même, dans la méthode edit, vous feriez:

def edit 
    @parent_object = ParentObject.find(params[:id]) 
    3.times { @parent_object.child_objects.build } 
end 

Pour le faire fonctionner , vous devez définir les attributs imbriqués pour l'objet enfant:

class ParentObject < ActiveRecord::Base 
    has_many :child_objects, :dependent => :destroy 
    accepts_nested_attributes_for :child_objects 
end  

Espérons que cela aide - c'est exactement ce que RB propose dans ses screencasts. Faites-moi savoir dans les commentaires si vous avez besoin d'explications supplémentaires.

- EDIT -

La méthode de mise à jour dans le parent_object_controller.rb est juste un standard:

def update 
    @parent_object = ParentObject.find(params[:id]) 
    if @parent_object.update_attributes(params[:parent_object]) 
    flash[:notice] = "Successfully updated parent object." 
    redirect_to @parent_object 
    else 
    render :action => 'edit' 
    end 
end 

Mais grâce à la accepts_nested_attributes_for dans le ParentObjet, les instances imbriquées sera également créé.

Je n'ai pas inclus tout le code du modèle et du contrôleur dans cette réponse. Vous pouvez voir le reste du code en téléchargeant source code for this episode depuis github.

+0

wow je ne peux pas vous remercier assez. Vraiment, ce screencast particulier est probablement le plus proche, je suis d'accord. Donc, le grand dilemme que je rencontre ici est que lorsque je clique sur "submit", ou "save", l'action restituée cherche l'action de mise à jour d'un parent_object .. ah .. se rapprocher ici. Je suppose que je dois juste mettre à jour quelque chose avec le contrôleur du parent? – Trip

+0

Le journal: 'Traitement Parent_ObjectsController # mise à jour (pour :: 1 au 2010-10-19 12:10:43) [PUT] Paramètres: {" commit "=>" Soumettre "," Child_Objects "=> {" nom "=" jhkhjk "," org_name "=>" jhkjhk "," ville "=>" kjhkjh "," email "=>" jhkjh "}," action "=>" mise à jour "," _method "=>" put "," authenticity_token "=>" F2ZA2/BilvDrcOv + 4XZ8Md63mbZBce/y9hIjJJZ42pw = "," id "=>" 1 "," controller "=>" Parent_Objects "}' ' – Trip

+0

Voir la mise à jour de ma réponse pour la' mise à jour' méthode. – Matt