How can I get rid of this nasty query in my Rails view template?
Yuck. It's bringing me down.
In my controller:
@assessor = Assessor.find(params[:id])
@assessor.answers.build if @assessor.answers.empty?
In my view:
= simple_form_for @assessor do |f|
- @assessor.candidates.each do |candidate|
- @assessor.assessment_competencies.each do |competency|
- if @assessor.answers.all?{|a| a.new_record?}
- competency.behaviors.each do |behavior|
= f.fields_for :answers do |f|
- @assessor.standard_answer_choices.each do |choice|
= f.input :assessor_id, :as => :hidden, :input_html => {:value => @assessor.id}
= f.input :candidate_id, :as => :hidden, :input_html => {:value => candidate.id}
= f.input :behavior_id, :as => :hidden, :input_html => {:value => behavior.id}
= f.input :competency_id, :as => :hidden, :input_html => {:value => competency.id}
开发者_StackOverflow中文版 = f.association :answer_choice, :collection => [choice], :as => :radio
- else
- competency.behaviors.each do |behavior|
- answer = Answer.find_or_create_by_behavior_id_and_assessor_id_and_candidate_id(behavior.id, @assessor.id, candidate.id)
= f.fields_for :answers, answer do |f|
= f.input :assessor_id, :as => :hidden, :input_html => {:value => @assessor.id}
= f.input :candidate_id, :as => :hidden, :input_html => {:value => candidate.id}
= f.input :behavior_id, :as => :hidden, :input_html => {:value => behavior.id}
= f.input :competency_id, :as => :hidden, :input_html => {:value => competency.id}
= f.association :answer_choice, :collection => [choice], :as => :radio
Oof, that is a gnarly one.
At the very least you can yank that repeated fields_for
block out into a helper:
module AssessorsHelper
def answers_fields f, candidate, behavior, competency, answer=nil
assessor = f.object
f.fields_for :answers, answer do |f|
f.hidden_field :assessor_id, :value => assessor.id
f.hidden_field :candidate_id, :value => candidate.id
f.hidden_field :behavior_id, :value => behavior.id
f.hidden_field :competency_id, :value => competency.id
f.association :answer_choice, :collection => [choice], :as => :radio
end
end
end
That'll cut your view down to this:
= simple_form_for @assessor do |f|
- @assessor.candidates.each do |candidate|
- @assessor.assessment_competencies.each do |competency|
- if @assessor.answers.all?{|a| a.new_record?}
- competency.behaviors.each do |behavior|
= answers_fields f, candidate, behavior, competency
- else
- competency.behaviors.each do |behavior|
- answer = @assessor.answers.find_or_create_by_behavior_id_and_candidate_id behavior, candidate
= answers_fields f, candidate, behavior, competency, answer
If you wanted you could break it down into a helper for each inner loop, but you get the idea.
精彩评论