class Quby::Questionnaires::Entities::Questionnaire
Constants
- RESPONDENT_TYPES
- VALID_LICENSES
Attributes
abortable[RW]
allow_hotkeys[RW]
allow_switch_to_bulk[RW]
attributes[R]
charts[RW]
check_key_clashes[RW]
whether to check for clashes between question input keys (HTML form keys)
check_score_keys_consistency[RW]
whether to check consistency of score subkeys during seed generation
deactivate_answers_requested_at[RW]
default_answer_value[RW]
description[RW]
extra_css[RW]
fields[R]
flags[RW]
key[RW]
language[RW]
last_update[RW]
leave_page_alert[RW]
license[RW]
licensor[RW]
lookup_tables[RW]
outcome_description[RW]
outcome_regeneration_requested_at[RW]
outcome_tables[RW]
panels[RW]
renderer_version[RW]
respondent_types[RW]
roqua_keys[RW]
sbg_domains[RW]
sbg_key[RW]
score_calculations[RW]
score_schemas[RW]
short_description[RW]
textvars[RW]
title[RW]
validate_html[RW]
If false, we don't check html for validity (for mate1 and mate1_pre)
Public Class Methods
new(key, attributes = {}, last_update: Time.now)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 32 def initialize(key, attributes = {}, last_update: Time.now) @key = key @attributes = attributes @sbg_domains = [] @last_update = Time.at(last_update.to_i) @score_calculations = {}.with_indifferent_access @charts = Charting::Charts.new @fields = Fields.new(self) @license = :unknown @renderer_version = :v1 @extra_css = "" @allow_switch_to_bulk = false @panels = [] @flags = {}.with_indifferent_access @textvars = {}.with_indifferent_access @language = :nl @respondent_types = [] @tags = OpenStruct.new @check_key_clashes = true @validate_html = true @score_schemas = {}.with_indifferent_access @outcome_tables = [] @check_score_keys_consistency = true @lookup_tables = {} end
Public Instance Methods
actions()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 256 def actions score_calculations.values.select(&:action) end
add_chart(chart)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 264 def add_chart(chart) charts.add chart end
add_flag(flag_options)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 268 def add_flag(flag_options) if flag_options[:internal] flag_key = flag_options[:key].to_sym else flag_key = "#{key}_#{flag_options[:key]}".to_sym end flag_options[:key] = flag_key fail(ArgumentError, "Flag '#{flag_key}' already defined") if flags.key?(flag_key) flags[flag_key] = Flag.new(**flag_options) end
add_outcome_table(outcome_table_options)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 393 def add_outcome_table(outcome_table_options) outcome_tables << OutcomeTable.new(**outcome_table_options, questionnaire: self) end
add_panel(panel)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 130 def add_panel(panel) @panels << panel end
add_score_calculation(builder)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 232 def add_score_calculation(builder) if score_calculations.key?(builder.key) fail InputKeyAlreadyDefined, "Score key `#{builder.key}` already defined." end score_calculations[builder.key] = builder end
add_score_schema(key, label, subschema_options)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 239 def add_score_schema(key, label, subschema_options) schema = Entities::ScoreSchema.new(key: key, label: label, subscore_schemas: subschema_options) schema.valid? schema.errors.each do |attribute, message| errors.add("Score schema '#{key}'", "#{attribute} #{message}") end score_schemas[key] = schema end
add_textvar(textvar_options)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 285 def add_textvar(textvar_options) textvar_key = "#{key}_#{textvar_options.fetch(:key)}".to_sym textvar_options[:key] = textvar_key validate_textvar_keys_unique(textvar_key) validate_depends_on_flag(textvar_key, textvar_options) textvars[textvar_key] = Textvar.new(textvar_options) end
answer_dsl_module()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 305 def answer_dsl_module # rubocop:disable Metrics/MethodLength # Have to put this in a local variable so the module definition block can access it questions_in_var = questions @answer_dsl_cache ||= Module.new do questions_in_var.each do |question| next if question&.key.blank? case question.type when :date question.components.each do |component| # assignment to 'value' hash must be done under string keys key = question.send("#{component}_key").to_s define_method(key) do self.value ||= Hash.new self.value[key] end define_method("#{key}=") do |v| self.value ||= Hash.new self.value[key] = v&.strip end end define_method(question.key) do self.value ||= Hash.new components = question.components.sort component_values = components.map do |component| value_key = question.send("#{component}_key").to_s self.value[value_key] end case components when [:day, :month, :year] component_values.reverse.take_while { |p| p.present? }.reverse.join('-') when [:month, :year] component_values.reject(&:blank?).join('-') when [:hour, :minute] component_values.all?(&:blank?) ? '' : component_values.join(':') end end when :check_box define_method(question.key) do self.value ||= Hash.new self.value[question.key.to_s] ||= Hash.new end question.options.each do |opt| next if opt&.key.blank? define_method("#{opt.key}") do self.value ||= Hash.new self.value[question.key.to_s] ||= Hash.new self.value[opt.key.to_s] ||= 0 end define_method("#{opt.key}=") do |v| v = v.to_i self.value ||= Hash.new self.value[question.key.to_s] ||= Hash.new self.value[question.key.to_s][opt.key.to_s] = v self.value[opt.key.to_s] = v end end else # Includes: # question.type == :radio # question.type == :scale # question.type == :select # question.type == :string # question.type == :textarea # question.type == :integer # question.type == :float define_method(question.key) do self.value ||= Hash.new self.value[question.key.to_s] end define_method(question.key.to_s + "=") do |v| self.value ||= Hash.new self.value[question.key.to_s] = v end end rescue nil end end end
as_json(options = {})
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 175 def as_json(options = {}) { key: key, title: title, description: description, outcomeDescription: outcome_description, shortDescription: short_description, panels: panels, fields: fields, flags: flags, textvars: textvars, validations: validations, visibilityRules: visibility_rules } end
completion()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 260 def completion score_calculations.values.select(&:completion).first end
default_textvars()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 299 def default_textvars textvars.select { |key, textvar| textvar.default.present? } .map { |key, textvar| [key, textvar.default] } .to_h end
filter_flags(given_flags)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 279 def filter_flags(given_flags) given_flags.select do |flag_key, _| flags.key? flag_key end end
filter_textvars(given_textvars)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 293 def filter_textvars(given_textvars) given_textvars.select do |textvar_key, _| textvars.key? textvar_key end end
find_plottable(key)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 252 def find_plottable(key) score_calculations[key] || question_hash.with_indifferent_access[key] end
key_in_use?(key)
click to toggle source
rubocop:enable Metrics/MethodLength
# File lib/quby/questionnaires/entities/questionnaire.rb, line 228 def key_in_use?(key) fields.key_in_use?(key) || score_calculations.key?(key) end
license=(type)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 170 def license=(type) fail ArgumentError, 'Invalid license' unless VALID_LICENSES.include?(type) @license = type end
questions()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 162 def questions question_hash.values end
questions_of_type(type)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 166 def questions_of_type(type) questions.select { |question| question.type == type } end
questions_tree()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 150 def questions_tree return @questions_tree_cache if @questions_tree_cache recurse = lambda do |question| [question, question.subquestions.map(&recurse)] end @questions_tree_cache = (@panels && @panels.map do |panel| panel.items.map { |item| recurse.call(item) if item.is_a?(Quby::Questionnaires::Entities::Question) } end) end
register_question(question)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 134 def register_question(question) fields.add(question) if question.sets_textvar && !textvars.key?(question.sets_textvar) fail "Undefined textvar: #{question.sets_textvar}" end end
scores()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 248 def scores score_calculations.values.select(&:score) end
to_codebook(options = {})
click to toggle source
rubocop:disable Metrics/MethodLength
# File lib/quby/questionnaires/entities/questionnaire.rb, line 192 def to_codebook(options = {}) output = [] output << title output << "Date unknown" output << "" options[:extra_vars]&.each do |var| output << "#{var[:key]} #{var[:type]}" output << "\"#{var[:description]}\"" output << "" end top_questions = panels.map do |panel| panel.items.select { |item| item.is_a? Question } end.flatten.compact top_questions.each do |question| output << question.to_codebook(self, options) output << "" end flags.each_value do |flag| output << flag.to_codebook(options) output << "" end textvars.each_value do |textvar| output << textvar.to_codebook(options) output << "" end output = output.join("\n") strip_tags(output.gsub(/\<([ 1-9])/, '<\1')).gsub("<", "<") end
to_param()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 126 def to_param key end
validate_questions()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 142 def validate_questions question_hash.each_value do |q| unless q.valid? q.errors.each { |attr, err| errors.add(attr, err) } end end end
validations()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 397 def validations @validations ||= fields.question_hash.values.flat_map do |question| question.validations.map do |validation| case validation[:type] when :answer_group_minimum, :answer_group_maximum Validation.new(validation.merge(field_keys: questions.select {|q| q.question_group == validation[:group]}.map(&:key))) else Validation.new(validation.merge(field_key: question.key)) end end end.uniq(&:config) end
visibility_rules()
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 410 def visibility_rules @visibility_rules ||= fields.question_hash.values.flat_map { |question| VisibilityRule.from(question) } \ + flags.values.flat_map { |flag| VisibilityRule.from_flag(flag) } end
Private Instance Methods
validate_depends_on_flag(textvar_key, textvar_options)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 417 def validate_depends_on_flag(textvar_key, textvar_options) if textvar_options[:depends_on_flag].present? && !flags.key?(textvar_options[:depends_on_flag]) fail(ArgumentError, "Textvar '#{textvar_key}' depends on nonexistent flag '#{textvar_options[:depends_on_flag]}'") end end
validate_textvar_keys_unique(textvar_key)
click to toggle source
# File lib/quby/questionnaires/entities/questionnaire.rb, line 424 def validate_textvar_keys_unique(textvar_key) fail(ArgumentError, "Textvar '#{textvar_key}' already defined") if textvars.key?(textvar_key) end