app/models/survey.rb
# frozen_string_literal: true
# A record to represent a survey. This is not an ActiveRecord-based model, just
# a place to centralize the survey-loading, processing in an object.
class Survey
include ActiveModel::Conversion
SURVEY_META_KEY = '_survey'.freeze
SURVEY_PARTICIPANTS = 'participants'.freeze
# Needed to make Rails forms happy
def model_name
ActiveModel::Name.new(Survey)
end
def persisted?
false
end
def initialize(arg)
fail ActiveRecord::NotFound if arg.nil?
hash = case arg
when String
YAML.load(File.open(Rails.root.join('config', 'surveys', "#{arg}.yml"))).merge('id' => arg)
when Hash
arg
else
fail 'Not implemented yet'
end
@hash = IceNine.deep_freeze(hash)
validate_survey
rescue Errno::ENOENT
raise ActiveRecord::RecordNotFound, "Survey #{arg} not found"
end
def intro
if @intro.nil?
@intro = @hash['intro']
# load a markdown file if specified
if @intro =~ /\.md$/
@intro = File.read(Rails.root.join('config', 'surveys', @intro))
end
end
@intro
end
def title
@hash['title']
end
def description
@hash['description']
end
def active?
!(@hash.key?('active') && @hash['active'] == false)
end
# Access params
def access_params
if @access_params.nil?
@access_params = @hash['access'] || {'type' => 'token'}
end
@access_params
end
def revoke_all_tokens
SurveyToken.revoke_all_for_survey(survey_id)
end
def survey_id
@hash['id']
end
alias id survey_id
def questions
if @questions.nil?
@questions = @hash['questions'].map {|h| Question.new(self, h) }
end
@questions
end
def valid_question_key?(key)
questions.detect {|q| q.key == key } != nil
end
def [](key)
questions.detect {|q| q.key == key }
end
def intersections
if @intersections.nil?
@intersections =
if @hash['intersections'].nil?
[]
else
@hash['intersections'].map {|h| Intersection.new(self, h) }
end
end
@intersections
end
def tally_for(field, value)
Tally.tally_for(survey_id, field, value)
end
def tallies(field)
Tally.where(survey_id: survey_id, field: field)
end
def count_participant
Tally.record(survey_id, SURVEY_META_KEY, SURVEY_PARTICIPANTS)
end
def participants
tally_for(SURVEY_META_KEY, SURVEY_PARTICIPANTS)
end
private
def validate_survey
fail 'You must include an id field in the survey' if survey_id.blank?
end
# def method_missing(method_sym, *arguments, &block)
# if @hash['questions'].any? {|h| h['key'] == method_sym.to_s }
# nil
# else
# super
# end
# end
end