Class: Fe::QuestionSet
- Inherits:
-
Object
- Object
- Fe::QuestionSet
- Defined in:
- app/models/fe/question_set.rb
Instance Attribute Summary collapse
-
#elements ⇒ Object
readonly
Returns the value of attribute elements.
-
#questions ⇒ Object
readonly
Returns the value of attribute questions.
Instance Method Summary collapse
-
#any_questions? ⇒ Boolean
def valid? valid = true @questions.each do |question| valid = false unless question.valid_response? # run through ALL questions end valid end.
-
#initialize(elements, answer_sheet) ⇒ QuestionSet
constructor
associate answers from database with a set of elements.
-
#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.
- #save ⇒ Object
-
#set_filter(options = {}) ⇒ Object
options should contain:.
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
#elements ⇒ Object (readonly)
Returns the value of attribute elements.
6 7 8 |
# File 'app/models/fe/question_set.rb', line 6 def elements @elements end |
#questions ⇒ Object (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
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 |
#save ⇒ Object
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( = {}) return if .nil? || .empty? filter = .delete(:filter) unless filter && filter.is_a?(Array) raise("expect options[:filter] to be an array") end filter_default = .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 |