2010-01-11 5 views
0

Dans mon application Ruby on Rails, je souhaite autoriser l'ajout/modification d'un modèle imbriqué lui-même associé à un modèle.Comment créer une association pour un modèle imbriqué dans un formulaire

model Survey 
    string title 
    has_many questions 

model Question 
    string question 
    belongs_to category 

model Category 
    string name 

Pour les besoins du raisonnement, nous allons supposer que l'utilisateur doit toujours avoir à entrer dans une nouvelle catégorie lors de la saisie d'une question (je ne pouvais pas trouver un meilleur exemple, soupir).

Dans mon model/survey/edit.html.erb j'ai une configuration fonctionnelle pour ajouter des questions et les sauvegarder. Cependant, quand j'ai ajouté le modèle Category à l'image, je suis maintenant confronté au problème que lors de l'ajout d'un nouveau Question, il n'y a pas de Category champ de nom correspondant affiché. Je suppose que c'est parce que même si j'appelle Question.new, je n'appelle pas question.category.build - et je n'ai aucune idée où/comment faire cela.

Mon edit.html.erb:

<h1>Editing Survey</h1> 

<%= render :partial => 'form' %> 

Mon _form.html.erb:

<% form_for(@survey) do |f| %> 
    <%= f.error_messages %> 

    <p> 
    <%= f.label :title %><br /> 
    <%= f.text_field :title %> 
    </p> 

    <div id="questions"> 
    <% f.fields_for :questions do |q| %> 
     <%= render :partial => 'question', :locals => { :pf => q } %> 
    <% end %> 
    </div> 

    <%= add_a_new_child_link("New question", f, :questions) %> 
<% end %> 

Mon _question.html.erb:

<div class="question"> 
    <%= pf.label :question %> 
    <%= pf.text_field :question %> 

    <% pf.fields_for :category do |c| %> 
    <p> 
     <%= c.label :name, "Category:" %> 
     <%= c.text_field :name %> 
    </p> 
    <% end %> 
</div> 

Répondre

0

Une solution rapide pour votre situation consiste à utiliser des attributs virtuels. EG, dans votre modèle Question:

def category_name=(new_name) 
if category then 
    category.name = new_name 
else 
    category = Category.new(:name => new_name) 
end 
end 

def category_name 
    return category.name if category 
    "" 
end 

Dans votre _question, il pas besoin d'utiliser emboîtées. Il suffit d'ajouter quelque chose comme:

<%= pf.text_field :category_name %> 

Je n'ai pas testé, mais vous avez probablement pris le ideea.

+0

J'ai effectivement résolu le problème moi-même, au lieu de Question.new je devais juste faire une question.category.build avant de passer la question à la fonction de générateur JS. Mais j'aime beaucoup ton idée, j'essaierai bientôt. – Steve

Questions connexes