ece517-p3/expertiza

View on GitHub
app/models/questionnaire.rb

Summary

Maintainability
A
0 mins
Test Coverage
class Questionnaire < ActiveRecord::Base
  # for doc on why we do it this way,
  # see http://blog.hasmanythrough.com/2007/1/15/basic-rails-association-cardinality
  has_many :questions, dependent: :destroy # the collection of questions associated with this Questionnaire
  belongs_to :instructor # the creator of this questionnaire
  has_many :assignment_questionnaires, dependent: :destroy
  has_many :assignments, through: :assignment_questionnaires
  has_one :questionnaire_node, foreign_key: 'node_object_id', dependent: :destroy

  validate :validate_questionnaire
  validates :name, presence: true
  validates :max_question_score, :min_question_score, numericality: true

  DEFAULT_MIN_QUESTION_SCORE = 0  # The lowest score that a reviewer can assign to any questionnaire question
  DEFAULT_MAX_QUESTION_SCORE = 5  # The highest score that a reviewer can assign to any questionnaire question
  DEFAULT_QUESTIONNAIRE_URL = "http://www.courses.ncsu.edu/csc517".freeze
  QUESTIONNAIRE_TYPES = ['ReviewQuestionnaire',    
                         'MetareviewQuestionnaire',    
                         'Author FeedbackQuestionnaire',    
                         'AuthorFeedbackQuestionnaire',    
                         'Teammate ReviewQuestionnaire',    
                         'TeammateReviewQuestionnaire',    
                         'SurveyQuestionnaire',    
                         'AssignmentSurveyQuestionnaire',    
                         'Assignment SurveyQuestionnaire',    
                         'Global SurveyQuestionnaire',    
                         'GlobalSurveyQuestionnaire',    
                         'Course SurveyQuestionnaire',    
                         'CourseSurveyQuestionnaire',    
                         'BookmarkratingQuestionnaire',    
                         'QuizQuestionnaire'].freeze
  has_paper_trail

  def get_weighted_score(assignment, scores)
    # create symbol for "varying rubrics" feature -Yang
    round = AssignmentQuestionnaire.find_by(assignment_id: assignment.id, questionnaire_id: self.id).used_in_round
    questionnaire_symbol = if !round.nil?
                             (self.symbol.to_s + round.to_s).to_sym
                           else
                             self.symbol
                           end
    compute_weighted_score(questionnaire_symbol, assignment, scores)
  end

  def compute_weighted_score(symbol, assignment, scores)
    aq = self.assignment_questionnaires.find_by(assignment_id: assignment.id)
    if !scores[symbol][:scores][:avg].nil?
      scores[symbol][:scores][:avg] * aq.questionnaire_weight / 100.0
    else
      0
    end
  end

  # Does this questionnaire contain true/false questions?
  def true_false_questions?
    questions.each {|question| return true if question.type == "Checkbox" }
    false
  end

  def delete
    self.assignments.each do |assignment|
      raise "The assignment #{assignment.name} uses this questionnaire.
            Do you want to <A href='../assignment/delete/#{assignment.id}'>delete</A> the assignment?"
    end

    self.questions.each(&:delete)

    node = QuestionnaireNode.find_by(node_object_id: self.id)
    node.destroy if node

    self.destroy
  end

  def max_possible_score
    results = Questionnaire.joins('INNER JOIN questions ON questions.questionnaire_id = questionnaires.id')
                           .select('SUM(questions.weight) * questionnaires.max_question_score as max_score')
                           .where('questionnaires.id = ?', self.id)
    results[0].max_score
  end

  # validate the entries for this questionnaire
  def validate_questionnaire
    errors.add(:max_question_score, "The maximum question score must be a positive integer.") if max_question_score < 1
    errors.add(:min_question_score, "The minimum question score must be less than the maximum") if min_question_score >= max_question_score

    results = Questionnaire.where("id <> ? and name = ? and instructor_id = ?", id, name, instructor_id)
    errors.add(:name, "Questionnaire names must be unique.") if results.present?
  end
end