Class: ResponseSet

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/response_set.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ ResponseSet

Instance methods



24
25
26
27
# File 'app/models/response_set.rb', line 24

def initialize(*args)
  super(*args)
  default_args
end

Instance Attribute Details

#current_section_idObject

Returns the value of attribute current_section_id.



18
19
20
# File 'app/models/response_set.rb', line 18

def current_section_id
  @current_section_id
end

Instance Method Details

#access_code=(val) ⇒ Object



34
35
36
37
38
39
# File 'app/models/response_set.rb', line 34

def access_code=(val)
  while ResponseSet.find_by_access_code(val)
    val = Surveyor.make_tiny_code
  end
  super
end

#all_dependenciesObject



174
175
176
177
# File 'app/models/response_set.rb', line 174

def all_dependencies
  arr = dependencies.partition{|d| d.is_met?(self) }
  {:show => arr[0].map{|d| d.question_group_id.nil? ? "question_#{d.question_id}" : "question_group_#{d.question_group_id}"}, :hide => arr[1].map{|d| d.question_group_id.nil? ? "question_#{d.question_id}" : "question_group_#{d.question_group_id}"}}
end

#all_things_hashObject



170
171
172
# File 'app/models/response_set.rb', line 170

def all_things_hash
  self.all_dependencies.merge(self.all_validations)
end

#all_validationsObject

def current_section_id

  # Do all surveys have a first section???
  @current_section_id || self.survey.sections.first.id
end


164
165
166
167
168
# File 'app/models/response_set.rb', line 164

def all_validations
  arr = validations.partition{|v| v.is_valid?(self) }
  { :valid   => arr[0].map{|v| "question_#{v.answer.question_id}"},
    :invalid => arr[1].map{|v| "question_#{v.answer.question_id}"} }
end

#clear_responsesObject



60
61
62
63
64
# File 'app/models/response_set.rb', line 60

def clear_responses
  question_ids = Question.find_all_by_survey_section_id(current_section_id).map(&:id)
  responses.select{|r| question_ids.include? r.question_id}.map(&:destroy)
  responses.reload
end

#complete!Object



113
114
115
# File 'app/models/response_set.rb', line 113

def complete!
  self.completed_at = Time.now
end

#correct?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'app/models/response_set.rb', line 117

def correct?
  responses.all?(&:correct?)
end

#correctness_hashObject



120
121
122
123
124
125
# File 'app/models/response_set.rb', line 120

def correctness_hash
  { :questions => survey.sections_with_questions.map(&:questions).flatten.compact.size,
    :responses => responses.compact.size,
    :correct => responses.find_all(&:correct?).compact.size
  }
end

#count_group_responses(questions) ⇒ Object

Returns the number of response groups (count of group responses enterted) for this question group



147
148
149
# File 'app/models/response_set.rb', line 147

def count_group_responses(questions)
  questions.map{|q| responses.select{|r| (r.question_id.to_i == q.id.to_i) && !r.response_group.nil?}.group_by(&:response_group).size }.max
end

#default_argsObject



29
30
31
32
# File 'app/models/response_set.rb', line 29

def default_args
  self.started_at ||= Time.now
  self.access_code = Surveyor.make_tiny_code
end

#diff(another_response_set) ⇒ Object

Compare the Q and A codes of 2 response sets and return hash of differences.



231
232
233
234
# File 'app/models/response_set.rb', line 231

def diff(another_response_set)
  ars = ResponseSet.find(another_response_set)
  self.q_and_a_codes_as_attributes.diff(ars.q_and_a_codes_as_attributes)
end

#is_answered?(question) ⇒ Boolean

Returns:

  • (Boolean)


139
140
141
# File 'app/models/response_set.rb', line 139

def is_answered?(question)
  %w(label image).include?(question.display_type) or !is_unanswered?(question)
end

#is_complete?Boolean

Returns:

  • (Boolean)


236
237
238
239
240
# File 'app/models/response_set.rb', line 236

def is_complete?
  #  eventually return the is_complete column value
#     false
  !self.completed_at.nil?
end

#is_the_same_as?(another_response_set) ⇒ Boolean

Compare the Q and A codes of 2 response sets and return boolean.

Returns:

  • (Boolean)


223
224
225
226
227
# File 'app/models/response_set.rb', line 223

def is_the_same_as?(another_response_set)
  ars = ResponseSet.find(another_response_set)
  (self.q_and_a_codes_as_attributes.diff(
    ars.q_and_a_codes_as_attributes)).blank?
end

#is_unanswered?(question) ⇒ Boolean

Returns:

  • (Boolean)


142
143
144
# File 'app/models/response_set.rb', line 142

def is_unanswered?(question)
  self.responses.detect{|r| r.question_id == question.id}.nil?
end

#mandatory_questions_complete?Boolean

Returns:

  • (Boolean)


126
127
128
# File 'app/models/response_set.rb', line 126

def mandatory_questions_complete?
  progress_hash[:triggered_mandatory] == progress_hash[:triggered_mandatory_completed]
end

#progress_hashObject



129
130
131
132
133
134
135
136
137
138
# File 'app/models/response_set.rb', line 129

def progress_hash
  qs = survey.sections_with_questions.map(&:questions).flatten
  ds = dependencies(qs.map(&:id))
  triggered = qs - ds.select{|d| !d.is_met?(self)}.map(&:question)
  { :questions => qs.compact.size,
    :triggered => triggered.compact.size,
    :triggered_mandatory => triggered.select{|q| q.mandatory?}.compact.size,
    :triggered_mandatory_completed => triggered.select{|q| q.mandatory? and is_answered?(q)}.compact.size
  }
end

#q_and_a_codesObject

Collect all of the question and answers coded for the Home Exposures questionnaire.

>> ResponseSet.last.q_and_a_codes

=> [[“how_often_vacuumed_12mos”, “1”], [“freq_grilled_meat_outside_12mos”, “2”], [“other_pest_community_sprayed”, “dogs”], [“year_home_built”, 1900], [“number_of_rooms_in_home”, 5]]



191
192
193
# File 'app/models/response_set.rb', line 191

def q_and_a_codes
  self.responses.collect(&:q_and_a_codes)
end

#q_and_a_codes_and_text_as_attributesObject Also known as: codes_and_text

Return a good chunk of info used when merging response sets into one home exposure response



214
215
216
217
218
# File 'app/models/response_set.rb', line 214

def q_and_a_codes_and_text_as_attributes
  h=Hash.new({:a_code => '', :a_text => '(no answer)', :q_text => ''})
  #  h.merge keeps h's defaults!!!  woohoo!
  h.merge(self.responses.collect(&:codes_and_text).inject(:merge)||{})
end

#q_and_a_codes_as_attributesObject

Collect all of the question and answers coded for the Home Exposures questionnaire.

>> ResponseSet.last.q_and_a_codes_as_attributes

=> “number_of_rooms_in_home”=>5, “year_home_built”=>1900, “cmty_sprayed_other_pest_12mos”=>“1”, “other_pest_community_sprayed”=>“dogs”

>> HomeExposureResponse.create( ResponseSet.find(7).q_and_a_codes_as_attributes)



208
209
210
# File 'app/models/response_set.rb', line 208

def q_and_a_codes_as_attributes
  Hash[*self.responses.collect(&:q_and_a_codes).flatten]
end

#response_attributes=(response_attributes) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/models/response_set.rb', line 66

def response_attributes=(response_attributes)
  response_attributes.each do |question_id, responses_hash|
    # Response.delete_all(["response_set_id =? AND question_id =?", self.id, question_id])
    if (answer_id = responses_hash[:answer_id]) 
      if (!responses_hash[:answer_id].empty?) # Dropdowns return answer id but have an empty value if they are not set... ignoring those.
        #radio or dropdown - only one response
        responses.build({:question_id => question_id, :answer_id => answer_id}.merge(responses_hash[answer_id] || {}))
      end
    else
      #possibly multiples responses - unresponded radios end up here too
      # we use the variable question_id, not the "question_id" in the response_hash
      responses_hash.delete_if{|k,v| k == "question_id"}.each do |answer_id, response_hash|
        unless response_hash.delete_if{|k,v| v.blank?}.empty?
          responses.build({:question_id => question_id, :answer_id => answer_id}.merge(response_hash))
        end
      end
    end
  end
end

#response_for(question_id, answer_id, group = nil) ⇒ Object



55
56
57
58
# File 'app/models/response_set.rb', line 55

def response_for(question_id, answer_id, group = nil)
  found = responses.detect{|r| r.question_id == question_id && r.answer_id == answer_id && r.response_group.to_s == group.to_s}
  found.blank? ? responses.new(:question_id => question_id, :answer_id => answer_id, :response_group => group) : found
end

#response_group_attributes=(response_attributes) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/models/response_set.rb', line 86

def response_group_attributes=(response_attributes)
  response_attributes.each do |question_id, responses_group_hash|
    # Response.delete_all(["response_set_id =? AND question_id =?", self.id, question_id])
    responses_group_hash.each do |response_group_number, group_hash|
      if (answer_id = group_hash[:answer_id]) # if group_hash has an answer_id key we treat it differently 
        if (!group_hash[:answer_id].empty?) # dropdowns return empty values in answer_ids if they are not selected
          #radio or dropdown - only one response
          responses.build({:question_id => question_id, :answer_id => answer_id, :response_group => response_group_number}.merge(group_hash[answer_id] || {}))
        end
      else
        #possibly multiples responses - unresponded radios end up here too
        # we use the variable question_id in the key, not the "question_id" in the response_hash... same with response_group key
        group_hash.delete_if{|k,v| (k == "question_id") or (k == "response_group")}.each do |answer_id, inner_hash|
          unless inner_hash.delete_if{|k,v| v.blank?}.empty?
            responses.build({:question_id => question_id, :answer_id => answer_id, :response_group => response_group_number}.merge(inner_hash))
          end
        end
      end
      
    end
  end
end

#save_responsesObject



109
110
111
# File 'app/models/response_set.rb', line 109

def save_responses
  responses.each{|response| response.save(false)}
end

#to_csvObject



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/models/response_set.rb', line 41

def to_csv
  qcols = Question.content_columns.map(&:name) - %w(created_at updated_at)
  acols = Answer.content_columns.map(&:name) - %w(created_at updated_at)
  rcols = Response.content_columns.map(&:name)
  require 'fastercsv'
  FCSV(result = "") do |csv|
    csv << qcols.map{|qcol| "question.#{qcol}"} + acols.map{|acol| "answer.#{acol}"} + rcols.map{|rcol| "response.#{rcol}"}
    responses.each do |response|
      csv << qcols.map{|qcol| response.question.send(qcol)} + acols.map{|acol| response.answer.send(acol)} + rcols.map{|rcol| response.send(rcol)}
    end
  end
  result
end

#unanswered_dependenciesObject



151
152
153
# File 'app/models/response_set.rb', line 151

def unanswered_dependencies
  dependencies.select{|d| d.is_met?(self) and self.is_unanswered?(d.question)}.map(&:question)
end