# [+Project:+] DMPRoadmap # [+Description:+] This model describes informmation about the phase of a plan, it's title, order of display and which template it belongs to. # # [+Created:+] 03/09/2014 # [+Copyright:+] Digital Curation Centre and University of California Curation Center class Phase < ActiveRecord::Base ## # Sort order: Number ASC default_scope { order(number: :asc) } ## # Associations belongs_to :template has_many :sections, -> { order(:number => :asc) }, dependent: :destroy has_many :questions, :through => :sections, dependent: :destroy ## # Possibly needed for active_admin # -relies on protected_attributes gem as syntax depricated in rails 4.2 attr_accessible :description, :number, :title, :template_id, :template, :sections, :modifiable, :as => [:default, :admin] validates :title, :number, :template, presence: {message: _("can't be blank")} scope :titles, -> (template_id) { Phase.where(template_id: template_id).select(:id, :title) } # EVALUATE CLASS AND INSTANCE METHODS BELOW # # What do they do? do they do it efficiently, and do we need them? # Callbacks after_save do |phase| # Updates the template.updated_at attribute whenever a phase has been created/updated phase.template.touch end ## # returns the title of the phase # # @return [String] the title of the phase def to_s "#{title}" end # TODO: This function does not belong here anymore. It may be useless now. ## # returns either the latest published version of this phase # also serves to verify if this phase has any published versions as returns nil # if there are no published versions # # @return [Version, nil] # def latest_published_version # pub_vers = versions.where('published = ?', true).order('updated_at DESC') # if pub_vers.any?() then # return pub_vers.first # else # return nil # end # end # TODO: reevaluate this method. It seems like the 1st query is unecessary ## # verify if a phase has a published version or a version with one or more sections # # @return [Boolean] =begin def has_sections versions = self.versions.where('published = ?', true).order('updated_at DESC') if versions.any? then version = versions.first if !version.sections.empty? then has_section = true else has_section = false end else version = self.versions.order('updated_at DESC').first if !version.sections.empty? then has_section = true else has_section = false end end return has_section end =end ## # deep copy the given phase and all it's associations # # @params [Phase] phase to be deep copied # @return [Phase] the saved, copied phase def self.deep_copy(phase) phase_copy = phase.dup phase_copy.save! phase.sections.each do |section| section_copy = Section.deep_copy(section) section_copy.phase_id = phase_copy.id section_copy.save! end return phase_copy end # Returns the number of answered question for the phase. def num_answered_questions(plan) return 0 if plan.nil? return sections.reduce(0) do |m, s| m + s.num_answered_questions(plan) end end # Returns the number of questions for a phase. Note, this method becomes useful # for when sections and their questions are eager loaded so that avoids SQL queries. def num_questions n = 0 self.sections.each do |s| n+= s.questions.size() end return n end end