Reputation: 6244
I have a rails 3 form that has 100+ questions. Each time a radio button associated with an answer is clicked the form returns the answers for all 100+ questions. So that would be 100 records updated for all 100 questions by the time someone is finished. A total of 10,000 record updates.
I am trying to think through how to change the code to update only one answer per click instead of all 100+.
The code is below if you want to go into that much detail. Thanks.
The form:
<%= form_tag update_result_answers_path, :remote => true do %>
<% @answers.each do |q| %>
<%= q[0].question %>
<% [ 1, 2, 3, 4, 5 ].each do |f| %>
<%= radio_button_tag q[1].id, f, f == q[1].score, :class => 'submittable' %>
<% end %>
<% end %>
<% end %>
application.js:
$('.submittable').live('change', function() {
$(this).parents('form:first').submit();
return false;
});
the controller:
def update_result
@answers = []
params[:answer].each_pair do |key,value|
ans = Answer.find(key.to_i)
ans.update_attributes(:score => value)
@answers << ans
end
render :nothing => true
end
Upvotes: 2
Views: 371
Reputation: 3815
Okay, I think I got the problem now. He is what I would do:
<%= form_tag update_score_answer_path(answer), :id => "answer_#{answer.id}_form", :remote => true do %>
<%= answer.question %> <%# didn't understand this here, maybe it's outside of the loop? %>
<% [ 1, 2, 3, 4, 5 ].each do |f| %>
<%= radio_button_tag answer.id, f, f == answer.score, :class => 'submittable' %>
<% end %>
<% end %>
Then loop through them:
<% @answers.each do |answer| %>
<%= render 'answers/answer_form', :answer => answer %>
<% end %>
Then on the controller
def update_score
@answer = Answer.find(params[:answer_id])
@answer.score = params[:answer][:score]
@answer.save
end
And respond with js
$('#answer_<%= @answer.id %>_form').replaceWith("<%= escape_javascript( render 'answers/answer_form', :answer => @answer ) %>")
The controller is probably not correct, but you get the picture. you can also just update the radio button if you'd like, just javascript being returned.
Hope this helps
Also, if needed, you can switch the renders with
render :partial => 'lala', :locals => { :answer => object }
Upvotes: 1