I'm trying to create a form that calls itself with cocoon, question has_many questions, is generating infinite loop :(
Model
class Question < ActiveRecord::Base
has_many :questions,:foreign_key => "parent_id", :dependent =>:destroy
belongs_to :basic_component
attr_accessible :description, :questions_attributes, :questions
end
my question _form
<%= semantic_form_for [:admin, @question] do |f| %>
<%= f.inputs do %>
<%= f.input :description %>
<div class="questions">
<%= f.semantic_fields_for :questions do |question| %>
<%= render 'question_fields', :f => question %>
<% end %>
<div class="links">
<%= link_to_add_association("Nova Pergunta", f, :questions, class: 'button') %>
</div>
</div>
<% end %>
<%= f.actions %>
<% end %>
my _question_fields
<div class="nested-fields">
<%= f.inputs do %>
<%= f.input :description} %>
<div class="questions">
<%= f.semantic_fields_for :questions do |question| %>
<%= render 'question_fields', :f => question %>
<% end %>
<div class="links">
<%= link_to_add_association("Nova Pergunta", f, :questions, class: 'button') %>
</div>
</div>
<% end %>
</div>
Infinite loop :(, how to solve?
Rendered admin/questions/_question_fields.html.erb (168.4ms)
Rendered admin/questions/_question_fields.html.erb (376.2ms)
Rendered admin/questions/_question_fields.html.erb (586.4ms)
Rendered admin/questions/_question_fields.html.erb (780.2ms)
The link_to_add_association
also pre-renders the nested form, at server side, so when the link is clicked, it can insert the "new" item.
So that is where your endless loop comes from: the link_to_add_association
renders the nested-form, which also renders the nested-form and the link_to_add_association
which also ... ad infinitum ;)
If you really want to be able to build an indefinite/unlimited tree, cocoon is not the tool for you. You will have to resort to using ajax.
However if you can limit the maximum depth, it is rather easy to add an extra parameter to the view which only renders the link_to_add_association
if the level is below your maximum level.
This has come up before in the cocoon issues, and a possible solution was demonstrated
In short, assume the maximum depth is 5, you do something like (haml for readability) :
= semantic_form_for [:admin, @question] do |f|
= f.inputs do
= f.input :description
.questions
= f.semantic_fields_for :questions do |question|
= render 'question_fields', f: question, depth: 0
.links
= link_to_add_association "Nova Pergunta", f, :questions,
class: 'button', render_options: {locals: {depth: 0}}
= f.actions
and your question_fields
partial then tests for this depth
(and propagates it)
.nested-fields
= f.inputs do
= f.input :description
.questions
= f.semantic_fields_for :questions do |question|
= render 'question_fields', :f => question, depth: depth + 1
- if depth < 5
.links
= link_to_add_association "Nova Pergunta", f, :questions,
class: 'button', render_options: {locals: {depth: depth + 1}}