开发者

Complex Model the Rails Way

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜