Class: Fe::Question
- Inherits:
-
Element
- Object
- ActiveRecord::Base
- ApplicationRecord
- Element
- Fe::Question
- Includes:
- ActionView::RecordIdentifier
- Defined in:
- app/models/fe/question.rb
Direct Known Subclasses
AttachmentField, ChoiceField, DateField, ReferenceQuestion, StateChooser, TextField
Instance Attribute Summary collapse
-
#answers ⇒ Object
a question has one response per AnswerSheet (that is, an instance of a user filling out the question) generally the response is a single answer however, “Choose Many” (checkbox) questions have multiple answers in a single response.
Attributes inherited from Element
Instance Method Summary collapse
- #check_answer_sheet_matches_set_response_answer_sheet(answer_sheet) ⇒ Object
-
#default_label? ⇒ Boolean
element view provides the element label with required indicator.
- #delete_file(answer_sheet, answer) ⇒ Object
- #display_response(answer_sheet) ⇒ Object
-
#has_response?(answer_sheet = nil) ⇒ Boolean
has any sort of non-empty response?.
-
#locked?(params, answer_sheet, presenter, current_person) ⇒ Boolean
NOTE: current_person is passed in for the benefit of enclosing apps that override locked? and need to lock an element depending on who the current person is.
-
#response(answer_sheet) ⇒ Object
shortcut to return first answer.
- #responses(answer_sheet) ⇒ Object
- #save_file(answer_sheet, file) ⇒ Object
-
#save_response(answer_sheet) ⇒ Object
save this question’s @answers to database.
-
#set_response(values, answer_sheet) ⇒ Object
set answers from posted response.
-
#validation_class(answer_sheet = nil, page = nil) ⇒ Object
css class names for javascript-based validation.
Methods inherited from Element
#all_elements, #conditional_answers, #conditional_match, #content, create_from_import, #css_classes, #duplicate, #export_hash, #export_to_yaml, #hidden?, #hidden_by_choice_field?, #hidden_by_conditional?, #label, #limit, #matches_filter, max_label_length, #page_id, #pages_on, #position, #previous_element, #ptemplate, #question?, #required?, #reuseable?, #set_conditional_element, #set_position, #tooltip, #update_any_previous_conditional_elements, #update_page_all_element_ids, #visibility_affecting_element_ids, #visibility_affecting_questions, #visible?
Instance Attribute Details
#answers ⇒ Object
a question has one response per AnswerSheet (that is, an instance of a user filling out the question) generally the response is a single answer however, “Choose Many” (checkbox) questions have multiple answers in a single response
54 55 56 |
# File 'app/models/fe/question.rb', line 54 def answers @answers end |
Instance Method Details
#check_answer_sheet_matches_set_response_answer_sheet(answer_sheet) ⇒ Object
220 221 222 223 224 |
# File 'app/models/fe/question.rb', line 220 def check_answer_sheet_matches_set_response_answer_sheet(answer_sheet) if @answer_sheet_answers_are_for && @answer_sheet_answers_are_for != answer_sheet fail("Trying to save answers to a different answer sheet than the one given in set_response") end end |
#default_label? ⇒ Boolean
element view provides the element label with required indicator
83 84 85 |
# File 'app/models/fe/question.rb', line 83 def default_label? true end |
#delete_file(answer_sheet, answer) ⇒ Object
232 233 234 235 |
# File 'app/models/fe/question.rb', line 232 def delete_file(answer_sheet, answer) check_answer_sheet_matches_set_response_answer_sheet(answer_sheet) answer.destroy end |
#display_response(answer_sheet) ⇒ Object
138 139 140 141 142 143 144 145 |
# File 'app/models/fe/question.rb', line 138 def display_response(answer_sheet) r = responses(answer_sheet) if r.blank? "" else r.join(", ") end end |
#has_response?(answer_sheet = nil) ⇒ Boolean
has any sort of non-empty response?
265 266 267 268 269 270 271 272 273 |
# File 'app/models/fe/question.rb', line 265 def has_response?(answer_sheet = nil) answers = answer_sheet.present? ? responses(answer_sheet) : sheet_answers return false if answers.length == 0 answers.each do |answer| value = answer.is_a?(Fe::Answer) ? answer.value : answer return true if (value.is_a?(FalseClass) && value === false) || value.present? end false end |
#locked?(params, answer_sheet, presenter, current_person) ⇒ Boolean
NOTE: current_person is passed in for the benefit of enclosing apps that override locked? and need to lock an element depending on who the current person is
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'app/models/fe/question.rb', line 89 def locked?(params, answer_sheet, presenter, current_person) return true if params['action'] == 'show' if self.object_name == 'person.current_address' && ['address1','address2','city','zip','email','state','country'].include?(self.attribute_name) # Billing Address return false elsif self.object_name == 'person.emergency_address' && ['address1','address2','city','zip','email','state','country','contactName','homePhone','workPhone'].include?(self.attribute_name) # Emergency Contact return false elsif self.label == 'Relationship To You' || self.style == "country" || (self.style == "email" && self.label == "Confirm Email") # Relationship & Country & Email Address return false else return answer_sheet.frozen? && !presenter&.reference? && !@answer_sheet.try(:reference?) end end |
#response(answer_sheet) ⇒ Object
shortcut to return first answer
134 135 136 |
# File 'app/models/fe/question.rb', line 134 def response(answer_sheet) responses(answer_sheet).first.to_s end |
#responses(answer_sheet) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'app/models/fe/question.rb', line 147 def responses(answer_sheet) return [] unless answer_sheet # try to find answer from external object if !object_name.blank? and !attribute_name.blank? obj = %w(answer_sheet application reference).include?(object_name) ? answer_sheet : eval("answer_sheet." + object_name) if obj.nil? or eval("obj." + attribute_name + ".nil?") [] else [eval("obj." + attribute_name)] end else answers = sheet_answers.where(answer_sheet: answer_sheet) answers = answers.where("value IS NOT NULL AND value != ''") answers.to_a end end |
#save_file(answer_sheet, file) ⇒ Object
226 227 228 229 230 |
# File 'app/models/fe/question.rb', line 226 def save_file(answer_sheet, file) check_answer_sheet_matches_set_response_answer_sheet(answer_sheet) @answers.collect(&:destroy) if @answers Fe::Answer.create!(question_id: self.id, answer_sheet_id: answer_sheet.id, attachment: file) end |
#save_response(answer_sheet) ⇒ Object
save this question’s @answers to database
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'app/models/fe/question.rb', line 238 def save_response(answer_sheet) check_answer_sheet_matches_set_response_answer_sheet(answer_sheet) unless @answers.nil? for answer in @answers if answer.is_a?(Fe::Answer) answer.answer_sheet_id = answer_sheet.id answer.save! end end end # remove others unless @mark_for_destroy.nil? for answer in @mark_for_destroy answer.destroy end @mark_for_destroy.clear end # clear hidden elements cache on page since this answer might modify which elements are hidden pages_on.each do |p| p.clear_all_hidden_elements; end rescue TypeError raise answer.inspect end |
#set_response(values, answer_sheet) ⇒ Object
set answers from posted response
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'app/models/fe/question.rb', line 166 def set_response(values, answer_sheet) values = Array.wrap(values) if !object_name.blank? and !attribute_name.blank? # if eval("answer_sheet." + object_name).present? object = %w(answer_sheet application).include?(object_name) ? answer_sheet : eval("answer_sheet." + object_name) unless object.present? if object_name.include?('.') objects = object_name.split('.') object = eval("answer_sheet." + objects[0..-2].join('.') + ".create_" + objects.last) eval("answer_sheet." + objects[0..-2].join('.')).reload end end unless responses(answer_sheet) == values value = values.first if self.is_a?(Fe::DateField) && value.present? begin value = Date.strptime(value, '%Y-%m-%d') rescue raise "invalid date - " + value.inspect end end object.update_attribute(attribute_name, value) end # else # raise object_name.inspect + ' == ' + attribute_name.inspect # end else @answers = sheet_answers.where(answer_sheet_id: answer_sheet.id).to_a @answer_sheet_answers_are_for = answer_sheet @mark_for_destroy ||= [] # go through existing answers (in reverse order, as we delete) (@answers.length - 1).downto(0) do |index| # reject: skip over responses that are unchanged unless values.reject! {|value| value == @answers[index]} # remove any answers that don't match the posted values @mark_for_destroy << @answers[index] # destroy from database later @answers.delete_at(index) end end # insert any new answers for value in values if @mark_for_destroy.empty? answer = Fe::Answer.new(question_id: self.id) else # re-use marked answers (an update vs. a delete+insert) answer = @mark_for_destroy.pop end answer.set(value) @answers << answer end end end |
#validation_class(answer_sheet = nil, page = nil) ⇒ Object
css class names for javascript-based validation
107 108 109 110 111 112 113 |
# File 'app/models/fe/question.rb', line 107 def validation_class(answer_sheet = nil, page = nil) if required?(answer_sheet, page) ' required ' else '' end end |