Module: SurveyorGui::Models::QuestionMethods

Includes:
QuestionAndGroupSharedMethods
Included in:
Question
Defined in:
lib/surveyor_gui/models/question_methods.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from QuestionAndGroupSharedMethods

#controlling_questions

Class Method Details

.included(base) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/surveyor_gui/models/question_methods.rb', line 7

def self.included(base)
  base.send :attr_accessor, :dummy_answer, :dummy_answer_array, :type, :decimals
  base.send :attr_writer, :grid_columns_textbox, :omit, :omit_text,
            :other, :other_text, :comments_text, :comments, :dropdown_column_count
  base.send :attr_accessible, :dummy_answer, :dummy_answer_array, :question_type, :question_type_id, :survey_section_id, :question_group_id,
            :text, :pick, :reference_identifier, :display_order, :display_type,
            :is_mandatory,  :prefix, :suffix, :answers_attributes, :decimals, :dependency_attributes,
            :hide_label, :dummy_blob, :dynamically_generate, :answers_textbox, :dropdown_column_count,
            :grid_columns_textbox, :grid_rows_textbox, :omit_text, :omit, :other, :other_text, :is_comment, :comments, :comments_text,
            :dynamic_source, :modifiable, :report_code, :question_group_attributes if
            defined? ActiveModel::MassAssignmentSecurity
  base.send :accepts_nested_attributes_for, :answers, :reject_if => lambda { |a| a[:text].blank?}, :allow_destroy => true
  base.send :belongs_to, :survey_section
  base.send :has_many, :responses
  base.send :has_many, :dependency_conditions, :through=>:dependency, :dependent => :destroy
  base.send :default_scope, lambda{ base.order('display_order')}
  base.send :scope, :by_display_order, -> {base.order('display_order')}
  ### everything below this point must be commented out to run the rake tasks.
  base.send :accepts_nested_attributes_for, :dependency, :reject_if => lambda { |d| d[:rule].blank?}, :allow_destroy => true
  ### everything below this point must be commented out to run the rake tasks.

  base.send :mount_uploader, :dummy_blob, BlobUploader
  base.send :belongs_to, :question_type

  base.send :validate, :no_responses
  base.send :before_destroy, :no_responses
  base.send :after_save, :build_complex_questions
  base.send :before_save, :make_room_for_question

  base.send :scope, :is_not_comment, -> { base.where(is_comment: false) }
  base.send :scope, :is_comment, -> { base.where(is_comment: true) }

  base.class_eval do

    def answers_attributes=(ans)
      #don't set answer.text if question_type = number.  In this case, text should get set by the prefix and suffix setters.
      #note: Surveyor uses the answer.text field to store prefix and suffix for numbers.
      #if not a number question, go ahead and set the text attribute as normal.
      if @question_type_id!="number" && !ans.empty? && ans["0"]
        ans["0"].merge!( {"original_choice"=>ans["0"]["text"]})
        assign_nested_attributes_for_collection_association(:answers, ans)
      end
    end
  end

end

Instance Method Details

#answers_textboxObject

def controlling_questions in QuestionAndGroupSharedMethods



283
284
285
# File 'lib/surveyor_gui/models/question_methods.rb', line 283

def answers_textbox
  self.answers.where('is_exclusive != ? and is_comment != ? and response_class != ?',true,true,"string").order('display_order asc').collect(&:text).join("\n")
end

#answers_textbox=(textbox) ⇒ Object



287
288
289
290
291
# File 'lib/surveyor_gui/models/question_methods.rb', line 287

def answers_textbox=(textbox)
  #change updated_at as a hack to force dirty record for change on answers_textbox
  write_attribute(:updated_at, Time.now)
  @answers_textbox=textbox
end

#build_complex_questionsObject



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/surveyor_gui/models/question_methods.rb', line 366

def build_complex_questions
  if (@answers_textbox && self.pick!="none") || @grid_columns_textbox || @grid_rows_textbox
    self.question_type.build_complex_question_structure(
      self,
      answers_textbox:      @answers_textbox,
      omit_text:            @omit_text,
      is_exclusive:         @omit=="1",
      other_text:           @other_text,
      other:                @other=="1",
      comments_text:        @comments_text,
      comments:             @comments=="1",
      grid_columns_textbox: @grid_columns_textbox,
      grid_rows_textbox:    @grid_rows_textbox)
  end
end

#commentsObject



311
312
313
314
315
316
317
# File 'lib/surveyor_gui/models/question_methods.rb', line 311

def comments
  if self.part_of_group?
    @comments = self.question_group.questions.where('is_comment=?',true).size > 0
  else
    @comments = self.answers.where('is_comment=?',true).size > 0
  end
end

#comments_textObject



319
320
321
322
323
324
325
326
# File 'lib/surveyor_gui/models/question_methods.rb', line 319

def comments_text
  if self.part_of_group?
    @comments_text = is_comment ? self.answers.first.text : "Comments"
  else
    answer = self.answers.where('is_comment=?',true).first
    @comments_text = (answer ? answer.text : "Comments")
  end
end

#default_argsObject



54
55
56
57
58
59
60
61
# File 'lib/surveyor_gui/models/question_methods.rb', line 54

def default_args
  self.is_mandatory ||= false
  self.display_type ||= "default"
  self.pick ||= "none"
  self.data_export_identifier ||= Surveyor::Common.normalize(text)
  self.short_text ||= text
  self.api_id ||= Surveyor::Common.generate_api_id
end


328
329
330
# File 'lib/surveyor_gui/models/question_methods.rb', line 328

def dropdown_column_count
  @dropdown_column_count = @dropdown_column_count || (self.question_group ? self.question_group.columns.size : 1)
end

#dynamically_generateObject



79
80
81
# File 'lib/surveyor_gui/models/question_methods.rb', line 79

def dynamically_generate
  'false'
end

#grid_columns_textboxObject



332
333
334
# File 'lib/surveyor_gui/models/question_methods.rb', line 332

def grid_columns_textbox
  self.answers.where('response_class != ? and is_exclusive = ?',"string",false).order('display_order asc').collect(&:text).join("\n")
end

#grid_rows_textboxObject



336
337
338
339
340
341
342
# File 'lib/surveyor_gui/models/question_methods.rb', line 336

def grid_rows_textbox
  if self.question_group && self.question_group.questions
    self.question_group.questions.where('is_comment=?',false).order('display_order asc').collect(&:text).join("\n")
  else
    nil
  end
end

#grid_rows_textbox=(textbox) ⇒ Object



361
362
363
364
# File 'lib/surveyor_gui/models/question_methods.rb', line 361

def grid_rows_textbox=(textbox)
  write_attribute(:text, textbox.match(/.*\r*/).to_s.strip)
  @grid_rows_textbox = textbox.gsub(/\r/,"")
end

#is_numbered?Boolean

Returns:

  • (Boolean)


253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/surveyor_gui/models/question_methods.rb', line 253

def is_numbered?
  case display_type
  when 'label'
    false
  else
    if part_of_group?
      if question_group.questions.last.id == self.id
        true
      else
        false
      end
    else
      true
    end
  end
end

#make_room_for_questionObject



390
391
392
393
394
395
396
397
398
# File 'lib/surveyor_gui/models/question_methods.rb', line 390

def make_room_for_question
  if new_record?
    if Question.where('survey_section_id = ? and display_order = ?',survey_section_id, display_order).size > 0
      Question.where(:survey_section_id => survey_section_id)
            .where("display_order >= ?", display_order)
            .update_all("display_order = display_order+1")
    end
  end
end

#next_display_orderObject



382
383
384
385
386
387
388
# File 'lib/surveyor_gui/models/question_methods.rb', line 382

def next_display_order
  if part_of_group?
    self.question_group.questions.last.display_order + 1
  else
    display_order + 1
  end
end

#no_responsesObject

prevent a question from being modified if responses have been submitted for the survey. Protects data integrity.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/surveyor_gui/models/question_methods.rb', line 64

def no_responses
  #below is code to fix a bizarre bug. When triggered by the "cut" function, for some reason survey_id is erased. Have not found reason yet. Temporary fix.
  if !survey_section && self.id
    self.reload
  end
  if self.id && self.survey_section && self.survey_section.survey
    #this will be a problem if two people are editing the survey at the same time and do a survey preview - highly unlikely though.
    self.survey_section.survey.response_sets.where('test_data = ?',true).each {|r| r.destroy}
  end
  if self.id && !survey_section.survey.template && survey_section.survey.response_sets.count>0
    errors.add(:base,"Reponses have already been collected for this survey, therefore it cannot be modified. Please create a new survey instead.")
    return false
  end
end

#omitObject



293
294
295
# File 'lib/surveyor_gui/models/question_methods.rb', line 293

def omit
  @omit = self.answers.where('is_exclusive = ?',true).size > 0
end

#omit_textObject



297
298
299
300
# File 'lib/surveyor_gui/models/question_methods.rb', line 297

def omit_text
  answer = self.answers.where('is_exclusive = ?',true).first
  @omit_text = (answer ? answer.text : "none of the above")
end

#otherObject



302
303
304
# File 'lib/surveyor_gui/models/question_methods.rb', line 302

def other
  @other = self.answers.where('response_class = ? and is_exclusive = ? and is_comment = ?',"string",false, false).size > 0
end

#other_textObject



306
307
308
309
# File 'lib/surveyor_gui/models/question_methods.rb', line 306

def other_text
  answer = self.answers.where('response_class = ? and is_exclusive = ? and is_comment = ?',"string", false, false).first
  @other_text = (answer ? answer.text : "Other")
end

#prefixObject

number prefix getter. splits a number question into the actual answer and it’s unit type. Eg, you might want a number to be prefixed with a dollar sign.



189
190
191
192
193
# File 'lib/surveyor_gui/models/question_methods.rb', line 189

def prefix
  if self.answers.first && self.answers.first.text.include?('|')
    self.answers.first.text.split('|')[0]
  end
end

#prefix=(pre) ⇒ Object

sets the number prefix



203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/surveyor_gui/models/question_methods.rb', line 203

def prefix=(pre)
  if @question_type_id=="number"
    if self.answers.blank?
      self.answers_attributes={'0'=>{'text'=>pre+'|'}} unless pre.blank?
    else
      if pre.blank?
        self.answers.first.text = 'default'
      else
        self.answers.first.text = pre+'|'
      end
    end
  end
end

#prep_not_picks(answer_type) ⇒ Object

if the question is not a pick from list of choices (but is a fill in the blank type question) and not multiple choice, this sets it accordingly.



174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/surveyor_gui/models/question_methods.rb', line 174

def prep_not_picks(answer_type)
  write_attribute(:pick, "none")
  write_attribute(:display_type,"default")
  if self.answers.blank?
    #self.answers_attributes={'0'=>{'text'=>'default','response_class'=>answer_type, 'hide_label' => answer_type=='float' ? false : true}}
    self.answers_attributes={'0'=>{'text'=>'default','response_class'=>answer_type, 'display_type' => answer_type=='float' ? 'default' : 'hidden_label'}}
  else
    self.answers.first.response_class=answer_type
    #self.answers.first.hide_label = answer_type=='float' ? false : true
    self.answers.first.display_type = answer_type=='float' ? 'default' : 'hidden_label'
  end
end

#prep_picksObject

If the question involves picking from a list of choices, this sets response class.



158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/surveyor_gui/models/question_methods.rb', line 158

def prep_picks
  #write_attribute(:display_type, self.display_type || "default")
  if self.display_type=='stars'
    response_class='integer'
  else
    response_class='answer'
  end
  if self.answers.blank?
    self.answers_attributes={'0'=>{'text'=>'default', 'response_class'=>response_class}}
  else
    self.answers.map{|a|a.response_class=response_class}
  end
end

#question_descriptionObject



248
249
250
251
# File 'lib/surveyor_gui/models/question_methods.rb', line 248

def question_description
  ## this is an expensive method - use sparingly
  is_numbered? ? question_number.to_s + ') ' + text : text
end

#question_group_attributes=(params) ⇒ Object



344
345
346
347
348
349
350
351
# File 'lib/surveyor_gui/models/question_methods.rb', line 344

def question_group_attributes=(params)
  if question_group
    question_group.update_attributes(params.except(:id))
    @question_group_attributes=params
  else
    QuestionGroup.create!(params)
  end
end

#question_numberObject



270
271
272
273
274
275
276
277
278
# File 'lib/surveyor_gui/models/question_methods.rb', line 270

def question_number
  ##this is an expensive method - use sparingly
  ##should consider adding question_number attribute to table in future
  if survey_section.id.nil?
    nil
  else
    _preceding_questions_numbered.count
  end
end

#question_typeObject

#generates descriptions for different types of questions, including those that use widgets



88
89
90
# File 'lib/surveyor_gui/models/question_methods.rb', line 88

def question_type
  @question_type = QuestionType.find(question_type_id)
end

#question_type_idObject



83
84
85
# File 'lib/surveyor_gui/models/question_methods.rb', line 83

def question_type_id
  QuestionType.categorize_question(self)
end

#question_type_id=(type) ⇒ Object

setter for question type. Sets both pick and display_type



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/surveyor_gui/models/question_methods.rb', line 94

def question_type_id=(type)
  case type
  when "grid_one"
    write_attribute(:pick, "one")
    prep_picks
    write_attribute(:display_type, "default")
    _update_group_id
  when "pick_one"
    write_attribute(:pick, "one")
    prep_picks
    write_attribute(:display_type, "default")
    _remove_group
  when "slider"
    write_attribute(:pick, "one")
    prep_picks
    write_attribute(:display_type, "slider")
  when "stars"
    write_attribute(:pick, "one")
    write_attribute(:display_type, "stars")
    prep_picks
  when "dropdown"
    write_attribute(:pick, "one")
    write_attribute(:display_type, "dropdown")
    prep_picks
  when "pick_any"
    write_attribute(:pick, "any")
    prep_picks
    write_attribute(:display_type, "default")
    _remove_group
  when "grid_any"
    write_attribute(:pick, "any")
    prep_picks
    write_attribute(:display_type, "default")
    _update_group_id
  when "grid_dropdown"
    write_attribute(:pick, "one")
    prep_picks
    write_attribute(:display_type, "dropdown")
    _update_group_id
  when "group_inline"
    _update_group_id
  when 'label'
    write_attribute(:pick, "none")
    write_attribute(:display_type, "label")
  when 'box'
    prep_not_picks('text')
  when 'number'
    prep_not_picks('float')
  when 'date'
    prep_not_picks('date')
  when 'time'
    prep_not_picks('time')
  when 'datetime'
    prep_not_picks('datetime')          
  when 'file'
    prep_not_picks('blob')
  when 'string'
    prep_not_picks('string')
  end
  @question_type_id = type
end

#repeater?Boolean

Returns:

  • (Boolean)


400
401
402
# File 'lib/surveyor_gui/models/question_methods.rb', line 400

def repeater?
  part_of_group? ? (question_group.display_type=="repeater" ? true : false ) : false
end

#suffixObject

number suffix getter. sometimes you want a number question to have a units of measure suffix, like “per day”



196
197
198
199
200
# File 'lib/surveyor_gui/models/question_methods.rb', line 196

def suffix
  if self.answers.first && self.answers.first.text.include?('|')
    self.answers.first.text.split('|')[1]
  end
end

#suffix=(suf) ⇒ Object

sets the number suffix



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/surveyor_gui/models/question_methods.rb', line 218

def suffix=(suf)
  if @question_type_id=="number"
    if self.answers.first.blank? || self.answers.first.text.blank?
      self.answers_attributes={'0'=>{'text'=>'|'+suf}} unless suf.blank?
    else
      if self.answers.first.text=='default'
        self.answers.first.text='|'+suf
      elsif self.answers.first.text.blank?
        self.answers.first.text = '|'+suf
      else
        self.answers.first.text=self.answers.first.text+suf
      end
    end
  end
end

#surveyresponse_class(response_sets) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/surveyor_gui/models/question_methods.rb', line 235

def surveyresponse_class(response_sets)
  if dependent?
    response_sets.each do |r|
      if triggered?(r)
        return nil
      end
    end
    return "q_hidden"
  else
    nil
  end
end

#text=(txt) ⇒ Object



353
354
355
356
357
358
359
# File 'lib/surveyor_gui/models/question_methods.rb', line 353

def text=(txt)
  write_attribute(:text, txt)
  if part_of_group? && question_group.display_type != "inline"
    question_group.update_attributes(text: txt)
  end
  @text = txt
end