surveyor 0.22.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +83 -0
  4. data/Gemfile.rails_version +7 -1
  5. data/README.md +114 -16
  6. data/Rakefile +15 -9
  7. data/app/inputs/quiet_input.rb +5 -0
  8. data/app/inputs/surveyor_check_boxes_input.rb +35 -0
  9. data/app/inputs/surveyor_radio_input.rb +18 -0
  10. data/app/views/partials/_answer.html.haml +4 -4
  11. data/app/views/partials/_question.html.haml +7 -7
  12. data/app/views/partials/_question_group.html.haml +9 -8
  13. data/app/views/surveyor/export.json.rabl +28 -25
  14. data/app/views/surveyor/new.html.haml +8 -5
  15. data/app/views/surveyor/show.json.rabl +3 -2
  16. data/ci-exec.sh +13 -7
  17. data/cucumber.yml +3 -3
  18. data/doc/REPRESENTATIONS.md +34 -0
  19. data/doc/api_id_schema.json +7 -0
  20. data/doc/response_set_schema.json +54 -0
  21. data/doc/surveyor question combinations.png +0 -0
  22. data/doc/surveyor_timestamp_schema.json +9 -0
  23. data/features/ajax_submissions.feature +140 -0
  24. data/features/export_to_json.feature +182 -34
  25. data/features/no_duplicates.feature +110 -0
  26. data/features/show_survey.feature +1 -1
  27. data/features/step_definitions/parser_steps.rb +25 -2
  28. data/features/step_definitions/surveyor_steps.rb +145 -20
  29. data/features/step_definitions/ui_steps.rb +3 -0
  30. data/features/support/database_cleaner.rb +16 -0
  31. data/features/support/env.rb +21 -17
  32. data/features/support/simultaneous_ajax.rb +101 -0
  33. data/features/support/single_quit_selenium_driver.rb +23 -0
  34. data/features/support/slow_updates.rb +18 -0
  35. data/features/surveyor.feature +174 -44
  36. data/features/surveyor_dependencies.feature +80 -39
  37. data/features/surveyor_parser.feature +114 -20
  38. data/features/z_redcap_parser.feature +0 -1
  39. data/lib/{generators/surveyor/templates/public → assets}/images/surveyor/next.gif +0 -0
  40. data/lib/{generators/surveyor/templates/public → assets}/images/surveyor/prev.gif +0 -0
  41. data/lib/{generators/surveyor/templates/public/stylesheets/surveyor → assets/images}/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  42. data/lib/{generators/surveyor/templates/public/stylesheets/surveyor → assets/images}/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  43. data/lib/{generators/surveyor/templates/public/stylesheets/surveyor → assets/images}/ui-bg_glass_65_ffffff_1x400.png +0 -0
  44. data/lib/{generators/surveyor/templates/public/stylesheets/surveyor → assets/images}/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  45. data/lib/assets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  46. data/lib/{generators/surveyor/templates/public/stylesheets/surveyor → assets/images}/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  47. data/lib/{generators/surveyor/templates/public/stylesheets/surveyor → assets/images}/ui-icons_ef8c08_256x240.png +0 -0
  48. data/lib/{generators/surveyor/templates/public/stylesheets/surveyor → assets/images}/ui-icons_ffffff_256x240.png +0 -0
  49. data/lib/{generators/surveyor/templates/public → assets}/javascripts/surveyor/jquery-ui-timepicker-addon.js +23 -23
  50. data/lib/{generators/surveyor/templates/public → assets}/javascripts/surveyor/jquery-ui.js +125 -125
  51. data/lib/assets/javascripts/surveyor/jquery.selectToUISlider.js +240 -0
  52. data/lib/{generators/surveyor/templates/public → assets}/javascripts/surveyor/jquery.surveyor.js +52 -57
  53. data/lib/{generators/surveyor/templates/public → assets}/javascripts/surveyor/jquery.tools.min.js +7 -7
  54. data/lib/{generators/surveyor/templates/public → assets}/stylesheets/surveyor/dateinput.css +13 -13
  55. data/lib/{generators/surveyor/templates/public → assets}/stylesheets/surveyor/jquery-ui-timepicker-addon.css +0 -0
  56. data/lib/{generators/surveyor/templates/public → assets}/stylesheets/surveyor/jquery-ui.custom.css +17 -17
  57. data/lib/{generators/surveyor/templates/public → assets}/stylesheets/surveyor/reset.css +1 -1
  58. data/lib/{generators/surveyor/templates/public → assets}/stylesheets/surveyor/results.css +0 -0
  59. data/lib/assets/stylesheets/surveyor/ui.slider.extras.css +110 -0
  60. data/lib/{generators/surveyor/templates/public/stylesheets/sass → assets/stylesheets}/surveyor.sass +15 -7
  61. data/lib/generators/surveyor/custom_generator.rb +3 -2
  62. data/lib/generators/surveyor/install_generator.rb +59 -17
  63. data/lib/generators/surveyor/templates/app/assets/javascripts/surveyor_all.js +5 -0
  64. data/lib/generators/surveyor/templates/app/assets/stylesheets/surveyor_all.css +9 -0
  65. data/lib/generators/surveyor/templates/app/controllers/surveyor_controller.rb +2 -1
  66. data/lib/generators/surveyor/templates/app/views/layouts/surveyor_custom.html.erb +1 -0
  67. data/lib/generators/surveyor/templates/config/locales/surveyor_es.yml +1 -0
  68. data/lib/generators/surveyor/templates/config/locales/surveyor_he.yml +1 -0
  69. data/lib/generators/surveyor/templates/db/migrate/add_api_id_to_question_groups.rb +1 -0
  70. data/lib/generators/surveyor/templates/db/migrate/add_api_ids.rb +1 -0
  71. data/lib/generators/surveyor/templates/db/migrate/add_api_ids_to_response_sets_and_responses.rb +1 -0
  72. data/lib/generators/surveyor/templates/db/migrate/add_correct_answer_id_to_questions.rb +1 -0
  73. data/lib/generators/surveyor/templates/db/migrate/add_default_value_to_answers.rb +1 -0
  74. data/lib/generators/surveyor/templates/db/migrate/add_display_order_to_surveys.rb +1 -0
  75. data/lib/generators/surveyor/templates/db/migrate/add_display_type_to_answers.rb +1 -0
  76. data/lib/generators/surveyor/templates/db/migrate/add_index_to_response_sets.rb +1 -0
  77. data/lib/generators/surveyor/templates/db/migrate/add_index_to_surveys.rb +1 -0
  78. data/lib/generators/surveyor/templates/db/migrate/add_section_id_to_responses.rb +1 -0
  79. data/lib/generators/surveyor/templates/db/migrate/add_unique_index_on_access_code_and_version_in_surveys.rb +10 -0
  80. data/lib/generators/surveyor/templates/db/migrate/add_unique_indicies.rb +3 -2
  81. data/lib/generators/surveyor/templates/db/migrate/add_version_to_surveys.rb +10 -0
  82. data/lib/generators/surveyor/templates/db/migrate/api_ids_must_be_unique.rb +23 -0
  83. data/lib/generators/surveyor/templates/db/migrate/create_answers.rb +6 -5
  84. data/lib/generators/surveyor/templates/db/migrate/create_dependencies.rb +2 -1
  85. data/lib/generators/surveyor/templates/db/migrate/create_dependency_conditions.rb +2 -1
  86. data/lib/generators/surveyor/templates/db/migrate/create_question_groups.rb +5 -4
  87. data/lib/generators/surveyor/templates/db/migrate/create_questions.rb +4 -3
  88. data/lib/generators/surveyor/templates/db/migrate/create_response_sets.rb +1 -0
  89. data/lib/generators/surveyor/templates/db/migrate/create_responses.rb +10 -9
  90. data/lib/generators/surveyor/templates/db/migrate/create_survey_sections.rb +5 -4
  91. data/lib/generators/surveyor/templates/db/migrate/create_surveys.rb +4 -3
  92. data/lib/generators/surveyor/templates/db/migrate/create_validation_conditions.rb +5 -4
  93. data/lib/generators/surveyor/templates/db/migrate/create_validations.rb +3 -2
  94. data/lib/generators/surveyor/templates/db/migrate/drop_unique_index_on_access_code_in_surveys.rb +10 -0
  95. data/lib/generators/surveyor/templates/db/migrate/update_blank_api_ids_on_question_group.rb +22 -0
  96. data/lib/generators/surveyor/templates/db/migrate/update_blank_versions_on_surveys.rb +13 -0
  97. data/lib/generators/surveyor/templates/surveys/date_survey.rb +1 -0
  98. data/lib/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +54 -24
  99. data/lib/generators/surveyor/templates/surveys/quiz.rb +1 -0
  100. data/lib/generators/surveyor/templates/{public/stylesheets/sass → vendor/assets/stylesheets}/custom.sass +1 -1
  101. data/lib/surveyor/common.rb +16 -31
  102. data/lib/surveyor/engine.rb +2 -4
  103. data/lib/surveyor/helpers/asset_pipeline.rb +13 -0
  104. data/lib/surveyor/helpers/formtastic_custom_input.rb +17 -0
  105. data/lib/surveyor/helpers/surveyor_helper_methods.rb +10 -8
  106. data/lib/surveyor/models/answer_methods.rb +3 -0
  107. data/lib/surveyor/models/dependency_condition_methods.rb +27 -28
  108. data/lib/surveyor/models/dependency_methods.rb +3 -0
  109. data/lib/surveyor/models/question_group_methods.rb +3 -0
  110. data/lib/surveyor/models/question_methods.rb +10 -7
  111. data/lib/surveyor/models/response_methods.rb +16 -0
  112. data/lib/surveyor/models/response_set_methods.rb +71 -64
  113. data/lib/surveyor/models/survey_methods.rb +19 -28
  114. data/lib/surveyor/models/survey_section_methods.rb +3 -0
  115. data/lib/surveyor/models/validation_condition_methods.rb +4 -2
  116. data/lib/surveyor/models/validation_methods.rb +3 -0
  117. data/lib/surveyor/parser.rb +198 -148
  118. data/lib/surveyor/redcap_parser.rb +120 -80
  119. data/lib/surveyor/surveyor_controller_methods.rb +86 -37
  120. data/lib/surveyor/version.rb +2 -2
  121. data/lib/surveyor.rb +5 -6
  122. data/lib/tasks/surveyor_tasks.rake +19 -7
  123. data/spec/controllers/surveyor_controller_spec.rb +166 -92
  124. data/spec/factories.rb +33 -32
  125. data/spec/helpers/formtastic_custom_input_spec.rb +16 -0
  126. data/spec/lib/common_spec.rb +0 -39
  127. data/spec/lib/redcap_parser_spec.rb +24 -24
  128. data/spec/models/answer_spec.rb +12 -0
  129. data/spec/models/dependency_condition_spec.rb +279 -323
  130. data/spec/models/dependency_spec.rb +10 -0
  131. data/spec/models/question_group_spec.rb +12 -0
  132. data/spec/models/question_spec.rb +12 -0
  133. data/spec/models/response_set_spec.rb +189 -139
  134. data/spec/models/response_spec.rb +60 -0
  135. data/spec/models/survey_section_spec.rb +9 -0
  136. data/spec/models/survey_spec.rb +72 -9
  137. data/spec/models/validation_condition_spec.rb +9 -1
  138. data/spec/models/validation_spec.rb +10 -0
  139. data/spec/spec_helper.rb +25 -6
  140. data/surveyor.gemspec +5 -4
  141. metadata +332 -291
  142. data/features/step_definitions/common_steps.rb +0 -3
  143. data/lib/formtastic/surveyor_builder.rb +0 -82
  144. data/lib/generators/surveyor/templates/public/javascripts/surveyor/jquery.blockUI.js +0 -499
@@ -19,6 +19,9 @@ module Surveyor
19
19
  end
20
20
  base.send :include, Surveyor::ActsAsResponse # includes "as" instance method
21
21
 
22
+ # Whitelisting attributes
23
+ base.send :attr_accessible, :response_set, :question, :answer, :date_value, :time_value, :response_set_id, :question_id, :answer_id, :datetime_value, :integer_value, :float_value, :unit, :text_value, :string_value, :response_other, :response_group, :survey_section_id
24
+
22
25
  # Class methods
23
26
  base.instance_eval do
24
27
  def applicable_attributes(attrs)
@@ -85,6 +88,19 @@ module Surveyor
85
88
  return "#{(self.string_value || self.text_value || self.integer_value || self.float_value || nil).to_s}"
86
89
  end
87
90
  end
91
+
92
+ def json_value
93
+ return nil if answer.response_class == "answer"
94
+
95
+ formats = {
96
+ 'datetime' => '%Y-%m-%dT%H:%M%:z',
97
+ 'date' => '%Y-%m-%d',
98
+ 'time' => '%H:%M'
99
+ }
100
+
101
+ found = formats[answer.response_class]
102
+ found ? datetime_value.strftime(found) : as(answer.response_class)
103
+ end
88
104
  end
89
105
  end
90
106
  end
@@ -1,5 +1,7 @@
1
1
  require 'fastercsv'
2
2
  require 'csv'
3
+ require 'rabl'
4
+
3
5
  module Surveyor
4
6
  module Models
5
7
  module ResponseSetMethods
@@ -23,71 +25,30 @@ module Surveyor
23
25
  # Attributes
24
26
  base.send :attr_protected, :completed_at
25
27
 
28
+ # Whitelisting attributes
29
+ base.send :attr_accessible, :survey, :responses_attributes, :user_id, :survey_id
30
+
31
+ base.send :before_create, :ensure_start_timestamp
32
+ base.send :before_create, :ensure_identifiers
33
+
26
34
  # Class methods
27
35
  base.instance_eval do
28
- def to_savable(hash_of_hashes)
29
- result = []
30
- (hash_of_hashes || {}).each_pair do |k, hash|
31
- hash = Response.applicable_attributes(hash)
32
- if has_blank_value?(hash)
33
- result << hash.merge!({:_destroy => '1'}).except('answer_id') if hash.has_key?('id')
34
- else
35
- result << hash
36
- end
37
- end
38
- result
39
- end
40
-
41
36
  def has_blank_value?(hash)
42
37
  return true if hash["answer_id"].blank?
43
38
  return false if (q = Question.find_by_id(hash["question_id"])) and q.pick == "one"
44
39
  hash.any?{|k,v| v.is_a?(Array) ? v.all?{|x| x.to_s.blank?} : v.to_s.blank?}
45
40
  end
46
-
47
- def trim_for_lookups(hash_of_hashes)
48
- result = {}
49
- (reject_or_destroy_blanks(hash_of_hashes) || {}).each_pair do |k, hash|
50
- result.merge!({k => {"question_id" => hash["question_id"], "answer_id" => hash["answer_id"]}.merge(hash.has_key?("response_group") ? {"response_group" => hash["response_group"]} : {} ).merge(hash.has_key?("id") ? {"id" => hash["id"]} : {} ).merge(hash.has_key?("_destroy") ? {"_destroy" => hash["_destroy"]} : {} )})
51
- end
52
- result
53
- end
54
-
55
- private
56
- def reject_or_destroy_blanks(hash_of_hashes)
57
- result = {}
58
- (hash_of_hashes || {}).each_pair do |k, hash|
59
- hash = Response.applicable_attributes(hash)
60
- if has_blank_value?(hash)
61
- result.merge!({k => hash.merge("_destroy" => "true")}) if hash.has_key?("id")
62
- else
63
- result.merge!({k => hash})
64
- end
65
- end
66
- result
67
- end
68
41
  end
69
42
  end
70
43
 
71
- # Instance methods
72
- def initialize(*args)
73
- super(*args)
74
- default_args
44
+ def ensure_start_timestamp
45
+ self.started_at ||= Time.now
75
46
  end
76
47
 
77
- def default_args
78
- self.started_at ||= Time.now
79
- self.access_code ||= random_unique_access_code
48
+ def ensure_identifiers
49
+ self.access_code ||= Surveyor::Common.make_tiny_code
80
50
  self.api_id ||= Surveyor::Common.generate_api_id
81
51
  end
82
-
83
- def random_unique_access_code
84
- val = Surveyor::Common.make_tiny_code
85
- while ResponseSet.find_by_access_code(val)
86
- val = Surveyor::Common.make_tiny_code
87
- end
88
- val
89
- end
90
- private :random_unique_access_code
91
52
 
92
53
  def to_csv(access_code = false, print_header = true)
93
54
  qcols = Question.content_columns.map(&:name) - %w(created_at updated_at)
@@ -95,20 +56,27 @@ module Surveyor
95
56
  rcols = Response.content_columns.map(&:name)
96
57
  csvlib = CSV.const_defined?(:Reader) ? FasterCSV : CSV
97
58
  result = csvlib.generate do |csv|
98
- csv << (access_code ? ["response set access code"] : []) + qcols.map{|qcol| "question.#{qcol}"} + acols.map{|acol| "answer.#{acol}"} + rcols.map{|rcol| "response.#{rcol}"} if print_header
59
+ if print_header
60
+ csv << (access_code ? ["response set access code"] : []) +
61
+ qcols.map{|qcol| "question.#{qcol}"} +
62
+ acols.map{|acol| "answer.#{acol}"} +
63
+ rcols.map{|rcol| "response.#{rcol}"}
64
+ end
99
65
  responses.each do |response|
100
- csv << (access_code ? [self.access_code] : []) + qcols.map{|qcol| response.question.send(qcol)} + acols.map{|acol| response.answer.send(acol)} + rcols.map{|rcol| response.send(rcol)}
66
+ csv << (access_code ? [self.access_code] : []) +
67
+ qcols.map{|qcol| response.question.send(qcol)} +
68
+ acols.map{|acol| response.answer.send(acol)} +
69
+ rcols.map{|rcol| response.send(rcol)}
101
70
  end
102
71
  end
103
72
  result
104
73
  end
105
-
106
- def to_json
107
- template_path = ActionController::Base.view_paths.find("show", ["surveyor"], false, {:handlers=>[:rabl], :locale=>[:en], :formats=>[:json]}, [], []).inspect
108
- engine = Rabl::Engine.new(File.read(template_path))
109
- engine.render(nil, {:object => self})
74
+
75
+ def as_json(options = nil)
76
+ template_paths = ActionController::Base.view_paths.collect(&:to_path)
77
+ Rabl.render(self, 'surveyor/show.json', :view_path => template_paths, :format => "hash")
110
78
  end
111
-
79
+
112
80
  def complete!
113
81
  self.completed_at = Time.now
114
82
  end
@@ -151,7 +119,11 @@ module Surveyor
151
119
 
152
120
  # Returns the number of response groups (count of group responses enterted) for this question group
153
121
  def count_group_responses(questions)
154
- 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
122
+ questions.map { |q|
123
+ responses.select { |r|
124
+ (r.question_id.to_i == q.id.to_i) && !r.response_group.nil?
125
+ }.group_by(&:response_group).size
126
+ }.max
155
127
  end
156
128
 
157
129
  def unanswered_dependencies
@@ -163,12 +135,17 @@ module Surveyor
163
135
  end
164
136
 
165
137
  def unanswered_question_group_dependencies
166
- dependencies.select{ |d| d.question_group && self.is_group_unanswered?(d.question_group) && d.is_met?(self) }.map(&:question_group)
138
+ dependencies.
139
+ select{ |d| d.question_group && self.is_group_unanswered?(d.question_group) && d.is_met?(self) }.
140
+ map(&:question_group)
167
141
  end
168
142
 
169
143
  def all_dependencies(question_ids = nil)
170
144
  arr = dependencies(question_ids).partition{|d| d.is_met?(self) }
171
- {:show => arr[0].map{|d| d.question_group_id.nil? ? "q_#{d.question_id}" : "g_#{d.question_group_id}"}, :hide => arr[1].map{|d| d.question_group_id.nil? ? "q_#{d.question_id}" : "g_#{d.question_group_id}"}}
145
+ {
146
+ :show => arr[0].map{|d| d.question_group_id.nil? ? "q_#{d.question_id}" : "g_#{d.question_group_id}"},
147
+ :hide => arr[1].map{|d| d.question_group_id.nil? ? "q_#{d.question_id}" : "g_#{d.question_group_id}"}
148
+ }
172
149
  end
173
150
 
174
151
  # Check existence of responses to questions from a given survey_section
@@ -176,11 +153,41 @@ module Surveyor
176
153
  !responses.any?{|r| r.survey_section_id == section.id}
177
154
  end
178
155
 
156
+ def update_from_ui_hash(ui_hash)
157
+ transaction do
158
+ ui_hash.each do |ord, response_hash|
159
+ api_id = response_hash['api_id']
160
+ fail "api_id missing from response #{ord}" unless api_id
161
+
162
+ existing = Response.where(:api_id => api_id).first
163
+ updateable_attributes = response_hash.reject { |k, v| k == 'api_id' }
164
+
165
+ if self.class.has_blank_value?(response_hash)
166
+ existing.destroy if existing
167
+ elsif existing
168
+ if existing.question_id.to_s != updateable_attributes['question_id']
169
+ fail "Illegal attempt to change question for response #{api_id}."
170
+ end
171
+
172
+ existing.update_attributes(updateable_attributes)
173
+ else
174
+ responses.build(updateable_attributes).tap do |r|
175
+ r.api_id = api_id
176
+ r.save!
177
+ end
178
+ end
179
+
180
+ end
181
+ end
182
+ end
183
+
179
184
  protected
180
185
 
181
186
  def dependencies(question_ids = nil)
182
- deps = Dependency.all(:include => :dependency_conditions, :conditions => {:dependency_conditions => {:question_id => question_ids || responses.map(&:question_id)}})
183
- # this is a work around for a bug in active_record in rails 2.3 which incorrectly eager-loads associatins when a condition clause includes an association limiter
187
+ deps = Dependency.all(:include => :dependency_conditions,
188
+ :conditions => {:dependency_conditions => {:question_id => question_ids || responses.map(&:question_id)}})
189
+ # this is a work around for a bug in active_record in rails 2.3 which incorrectly eager-loads associatins when a
190
+ # condition clause includes an association limiter
184
191
  deps.each{|d| d.dependency_conditions.reload}
185
192
  deps
186
193
  end
@@ -1,4 +1,5 @@
1
1
  require 'surveyor/common'
2
+ require 'rabl'
2
3
 
3
4
  module Surveyor
4
5
  module Models
@@ -16,10 +17,13 @@ module Surveyor
16
17
  unless @@validations_already_included
17
18
  # Validations
18
19
  base.send :validates_presence_of, :title
19
- base.send :validates_uniqueness_of, :access_code
20
+ base.send :validates_uniqueness_of, :survey_version, :scope => :access_code, :message => "survey with matching access code and version already exists"
20
21
 
21
22
  @@validations_already_included = true
22
- end
23
+ end
24
+
25
+ # Whitelisting attributes
26
+ base.send :attr_accessible, :title, :description, :reference_identifier, :data_export_identifier, :common_namespace, :common_identifier, :css_url, :custom_class, :display_order
23
27
 
24
28
  # Class methods
25
29
  base.instance_eval do
@@ -37,21 +41,16 @@ module Surveyor
37
41
  end
38
42
 
39
43
  def default_args
40
- self.inactive_at ||= DateTime.now
41
44
  self.api_id ||= Surveyor::Common.generate_api_id
42
45
  self.display_order ||= Survey.count
43
46
  end
44
47
 
45
48
  def title=(value)
46
49
  return if value == self.title
47
- adjusted_value = value
48
- while Survey.find_by_access_code(Survey.to_normalized_string(adjusted_value))
49
- i ||= 0
50
- i += 1
51
- adjusted_value = "#{value} #{i.to_s}"
52
- end
53
- self.access_code = Survey.to_normalized_string(adjusted_value)
54
- super(adjusted_value)
50
+ surveys = Survey.where(:access_code => Survey.to_normalized_string(value)).order("survey_version DESC")
51
+ self.survey_version = surveys.first.survey_version.to_i + 1 if surveys.any?
52
+ self.access_code = Survey.to_normalized_string(value)
53
+ super(value)
55
54
  # self.access_code = Survey.to_normalized_string(value)
56
55
  # super
57
56
  end
@@ -59,29 +58,21 @@ module Surveyor
59
58
  def active?
60
59
  self.active_as_of?(DateTime.now)
61
60
  end
62
- def active_as_of?(datetime)
63
- (self.active_at.nil? or self.active_at < datetime) and (self.inactive_at.nil? or self.inactive_at > datetime)
64
- end
61
+ def active_as_of?(date)
62
+ (active_at && active_at < date && (!inactive_at || inactive_at > date)) ? true : false
63
+ end
65
64
  def activate!
66
65
  self.active_at = DateTime.now
66
+ self.inactive_at = nil
67
67
  end
68
68
  def deactivate!
69
69
  self.inactive_at = DateTime.now
70
+ self.active_at = nil
70
71
  end
71
- def active_at=(datetime)
72
- self.inactive_at = nil if !datetime.nil? and !self.inactive_at.nil? and self.inactive_at < datetime
73
- super(datetime)
74
- end
75
- def inactive_at=(datetime)
76
- self.active_at = nil if !datetime.nil? and !self.active_at.nil? and self.active_at > datetime
77
- super(datetime)
78
- end
79
- def to_json
80
- template_path = ActionController::Base.view_paths.find("export", ["surveyor"], false, {:handlers=>[:rabl], :locale=>[:en], :formats=>[:json]}, [], []).inspect
81
- engine = Rabl::Engine.new(File.read(template_path))
82
- engine.render(nil, {:object => self})
83
- end
84
-
72
+ def as_json(options = nil)
73
+ template_paths = ActionController::Base.view_paths.collect(&:to_path)
74
+ Rabl.render(self, 'surveyor/export.json', :view_path => template_paths, :format => "hash")
75
+ end
85
76
  end
86
77
  end
87
78
  end
@@ -19,6 +19,9 @@ module Surveyor
19
19
 
20
20
  @@validations_already_included = true
21
21
  end
22
+
23
+ # Whitelisting attributes
24
+ base.send :attr_accessible, :survey, :survey_id, :title, :description, :reference_identifier, :data_export_identifier, :common_namespace, :common_identifier, :display_order, :custom_class
22
25
  end
23
26
 
24
27
  # Instance Methods
@@ -6,7 +6,6 @@ module Surveyor
6
6
  base.send :belongs_to, :validation
7
7
 
8
8
  # Scopes
9
-
10
9
  @@validations_already_included ||= nil
11
10
  unless @@validations_already_included
12
11
  # Validations
@@ -20,7 +19,10 @@ module Surveyor
20
19
  end
21
20
 
22
21
  base.send :include, Surveyor::ActsAsResponse # includes "as" instance method
23
-
22
+
23
+ # Whitelisting attributes
24
+ base.send :attr_accessible, :validation, :validation_id, :rule_key, :operator, :question_id, :answer_id, :datetime_value, :integer_value, :float_value, :unit, :text_value, :string_value, :response_other, :regexp
25
+
24
26
  # Class methods
25
27
  base.instance_eval do
26
28
  def operators
@@ -18,6 +18,9 @@ module Surveyor
18
18
 
19
19
  @@validations_already_included = true
20
20
  end
21
+
22
+ # Whitelisting attributes
23
+ base.send :attr_accessible, :answer, :answer_id, :rule, :message
21
24
  end
22
25
 
23
26
  # Instance Methods