Class: Fe::QuestionSet

Inherits:
Object
  • Object
show all
Defined in:
app/models/fe/question_set.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(elements, answer_sheet) ⇒ QuestionSet

associate answers from database with a set of elements



9
10
11
12
13
# File 'app/models/fe/question_set.rb', line 9

def initialize(elements, answer_sheet)
  @elements = elements
  @answer_sheet = answer_sheet
  @questions = elements.select { |e| e.question? }
end

Instance Attribute Details

#elementsObject (readonly)

Returns the value of attribute elements.



6
7
8
# File 'app/models/fe/question_set.rb', line 6

def elements
  @elements
end

#questionsObject (readonly)

Returns the value of attribute questions.



6
7
8
# File 'app/models/fe/question_set.rb', line 6

def questions
  @questions
end

Instance Method Details

#any_questions?Boolean

def valid?

valid = true
@questions.each do |question|
  valid = false unless question.valid_response?  # run through ALL questions
end
valid

end

Returns:

  • (Boolean)


44
45
46
# File 'app/models/fe/question_set.rb', line 44

def any_questions?
  @questions.length > 0
end

#post(params, answer_sheet, cached_answers = nil) ⇒ Object

update with responses from form cached_answers: optional array of pre-loaded Fe::Answer records for this page,

avoids N per-question DB queries in set_response


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'app/models/fe/question_set.rb', line 18

def post(params, answer_sheet, cached_answers = nil)
  questions_indexed = @questions.index_by(&:id)

  # group cached answers by question_id for O(1) lookup
  answers_by_question = cached_answers&.group_by(&:question_id) || {}

  # loop over form values
  params ||= {}
  # we only assign answers to questions from this set, so it's fine to use to_unsafe_h here.  If we don't,
  # the kind_of?(Hash) checks will fail as per rails 5
  params.to_unsafe_h.each do |question_id, response|
    next if questions_indexed[question_id.to_i].nil? # the rare case where a question was removed after the app was opened.
    # update each question with the posted response
    question_answers = answers_by_question[question_id.to_i]
    questions_indexed[question_id.to_i].set_response(posted_values(response), answer_sheet, question_answers)
  end
end

#saveObject



48
49
50
51
52
53
54
# File 'app/models/fe/question_set.rb', line 48

def save
  AnswerSheet.transaction do
    @questions.each do |question|
      question.save_response(@answer_sheet)
    end
  end
end

#set_filter(options = {}) ⇒ Object

options should contain:

:filter - Array of symbols, ex [ :confidential ]

These will be called on each element to determine if they match the filter
An element matches the filter using an AND condition, ie. if all the methods
in the array return true

:filter_default - Either :show or :hide

If show, all elements are shown by default and hidden if they match the filter.
If hide, all elements are hidden by default and shown if they match the filter.


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'app/models/fe/question_set.rb', line 69

def set_filter(options = {})
  return if options.nil? || options.empty?

  filter = options.delete(:filter)
  unless filter && filter.is_a?(Array)
    raise("expect options[:filter] to be an array")
  end
  filter_default = options.delete(:filter_default)
  unless filter_default && [:show, :hide].include?(filter_default)
    raise("expect options[:filter_default] to be either :show or :hide")
  end

  @filter = filter
  @filter_default = filter_default

  matching_ids = []
  @elements.each do |e|
    if e.matches_filter(@filter) && !matching_ids.include?(e.id)
      matching_ids << e.id
      matching_ids += e.all_elements.collect(&:id)
    end
  end

  case filter_default
  when :show
    @elements = @elements.to_a.reject{ |e| matching_ids.include?(e.id) }
  when :hide
    @elements = @elements.to_a.select{ |e| matching_ids.include?(e.id) }
  end

  initialize(@elements, @answer_sheet)
end