Reputation: 558
I'm trying to implement a user feedback collection system to my Rails 3.2.13 app.
In my _footer partial (which is rendered in the layouts/application.html.erb file), I've included the feedback form as follows:
layouts/_footer.html.erb:
<footer class="footer dropup pull-right">
<nav>
<div id="fat-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
We'd Love Your Feedback!<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li></li>
<div id="feedback_form">
<%= render 'feedbacks/form' %>
</div>
</ul>
</nav>
</footer>
feedbacks/_form.html.erb:
<% @feedback = Feedback.new %>
<%= form_for(@feedback) do |f| %>
<% if signed_in? %>
<%= f.hidden_field :user_id %>
<% end %>
<div class="feedback_text">
<%= f.text_area :text %>
</div>
<div id="submit_feedback"><%= f.submit "Submit", class: "btn btn-primary" %></div>
<% end %>
<script>
$('#submit_feedback').click(function(){
$('#feedback_form').html("<%= escape_javascript(render 'feedbacks/after_submit') %>");
});
</script>
feedbacks/_after_submit.html.erb:
<div id="new_feeeback">
Submit a new feedback.
</div>
<script>
$('#new_feeeback').click(function(){
$('#feedback_form').html("<%= escape_javascript(render 'feedbacks/form') %>");
});
</script>
I feel an infinite loop like this is necessary for my case, since the rendering isn't triggered until the user clicks on the appropriate spots.
But Rails won't let me do it, as I got the
stack level too deep
error. Please let me know if there is a workaround, or a better approach altogether. It would be much appreciated!
Here's the trace:
Trace of template inclusion: app/views/feedbacks/_after_submit.html.erb, app/views/feedbacks/_form.html.erb, app/views/feedbacks/_after_submit.html.erb, app/views/feedbacks/_form.html.erb, app/views/feedbacks/_after_submit.html.erb, app/views/feedbacks/_form.html.erb, app/views/feedbacks/_after_submit.html.erb... and so on
P.S. I am aware that tags are not the best practice, I'm doing this now only to illustrate my approach more clearly.
Upvotes: 0
Views: 613
Reputation: 1118
To put it another way - ruby is substituting the content of the template at render time, not at click time so your form template is expanding out within the <%= %> brackets, which includes the after_submit content, which contains a <%= %> which expands to contain the form template, which contains a <%= %> expanding the after_submit, which contains a..... you see how this could be problematic....
Upvotes: 0
Reputation: 1398
Scenarios when I have encountered Stack Level too deep error:
1) Trying to include the same file in itself . EG The first line inside colors.js being @export colors
2) Naming a variable same as a function. Often subconsciously, we tend to do this mistake and we end up calling a function recursively instead of using a variable and performing some action.
So as an answer to the above question: The exception is not inside the views but in the controller. Please check the functions inside the feedbacks controller for loops.
Upvotes: 0
Reputation: 3925
One of the solution may be to use ajax to send the data and render returned data from server. Update your _form.html.erb something like this:
$('#feedback_form form').on('submit', function(){
$.ajax($(this).attr('action'), {
type: $(this).attr('method'),
data: $(this).serializeArray()
}).done(function(data) {
$('#feedback_form').html(data);
});
return false;
});
And update your controller to return _after_submit.html.erb page.
Upvotes: 1