I'm implementing questionnaires on a site. There are multiple questionnaires, each have sections, each section has questions. Users can fill out zero or many questionnaires.
model code below. ERD image http://i.stack.imgur.com/6Y0r3.png
What would be the "Rails Way" for storing/displaying question results while maintaining section hierarchy in the view? I don't mind writing code, but wasn't sure if I was missing something obvious. I've started with methods in the Question model but it doesn't take advantage of Form Helpers and the like.
#Simplistic view code
%h1= @user_questionnaire.questionnaire.value
- for section in @user_questionnaire.questionnaire.sections
%h4=section.value
%br
- for question in section.questions
=question.value
=question.result(@user_questionnaire.id)
Any thoughts are welcome. Thanks! Donald
Model Code
class Questionnaire < ActiveRecord::Base
has_many :开发者_C百科sections
has_many :user_questionnaires
end
class Section < ActiveRecord::Base
belongs_to :questionnaire
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :section
has_many :user_questionnaire_results
def result(uq_id)
uqr = UserQuestionnaireResult.where(:question_id => self.id, :user_questionnaire_id => uq_id).first
uqr.result
end
end
class UserQuestionnaire < ActiveRecord::Base
belongs_to :questionnaire
has_many :user_questionnaire_results
belongs_to :user
end
class UserQuestionnaireResult < ActiveRecord::Base
belongs_to :user_questionnaire
belongs_to :question
end
What's wrong with your result(uq_id)
method is that it will query DB for every result, which is slow and consty resource-wise. What you could do is to use joins
or includes
methods to optimize your DB access. So in your model:
class UserQuestionnaire
def self.includes_questions
includes :questionnaire => {:sections => [:questions]}
end
def loaded_result question
user_questionnaire_results.to_a.find { |r| r.question_id == question.id }
end
end
Then in controller:
@user_questionnaire = UserQuestionnaire.includes_questions.find params[:id]
And in view instead of =question.result(@user_questionnaire.id)
use:
= @user_questionnaire.loaded_result question
The idea is that you load from DB all sections, questions and result togather, not each separate instance. In the same manner you may try to play with joins
function and see if it's better for you.
Check logs or console in dev env to see which queries are executed.
精彩评论