jakewendt-surveyor 0.11.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +285 -0
  3. data/Rakefile +54 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/surveyor_controller.rb +142 -0
  6. data/app/helpers/survey_form_builder.rb +37 -0
  7. data/app/helpers/surveyor_helper.rb +67 -0
  8. data/app/models/answer.rb +23 -0
  9. data/app/models/dependency.rb +50 -0
  10. data/app/models/dependency_condition.rb +47 -0
  11. data/app/models/question.rb +54 -0
  12. data/app/models/question_group.rb +33 -0
  13. data/app/models/response.rb +94 -0
  14. data/app/models/response_set.rb +316 -0
  15. data/app/models/survey.rb +172 -0
  16. data/app/models/survey_section.rb +18 -0
  17. data/app/models/validation.rb +38 -0
  18. data/app/models/validation_condition.rb +47 -0
  19. data/app/views/layouts/surveyor_default.html.erb +13 -0
  20. data/app/views/partials/_answer.html.haml +58 -0
  21. data/app/views/partials/_question.html.haml +80 -0
  22. data/app/views/partials/_question_group.html.haml +39 -0
  23. data/app/views/surveyor/edit.html.haml +38 -0
  24. data/app/views/surveyor/new.html.haml +16 -0
  25. data/app/views/surveyor/show.html.haml +12 -0
  26. data/config/routes.rb +11 -0
  27. data/features/step_definitions/surveyor_steps.rb +7 -0
  28. data/features/step_definitions/web_steps.rb +273 -0
  29. data/features/support/env.rb +57 -0
  30. data/features/support/paths.rb +25 -0
  31. data/features/surveyor.feature +11 -0
  32. data/generators/extend_surveyor/extend_surveyor_generator.rb +22 -0
  33. data/generators/extend_surveyor/templates/EXTENDING_SURVEYOR +17 -0
  34. data/generators/extend_surveyor/templates/extensions/survey_extensions.rb +24 -0
  35. data/generators/extend_surveyor/templates/extensions/surveyor_controller_extensions.rb +28 -0
  36. data/generators/extend_surveyor/templates/extensions/surveyor_custom.html.erb +13 -0
  37. data/generators/extend_surveyor/templates/extensions/surveyor_helper_extensions.rb +17 -0
  38. data/generators/surveyor/surveyor_generator.rb +67 -0
  39. data/generators/surveyor/templates/README +10 -0
  40. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_leftright.gif +0 -0
  41. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_updown.gif +0 -0
  42. data/generators/surveyor/templates/assets/images/222222_11x11_icon_close.gif +0 -0
  43. data/generators/surveyor/templates/assets/images/222222_11x11_icon_doc.gif +0 -0
  44. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_closed.gif +0 -0
  45. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_open.gif +0 -0
  46. data/generators/surveyor/templates/assets/images/222222_11x11_icon_minus.gif +0 -0
  47. data/generators/surveyor/templates/assets/images/222222_11x11_icon_plus.gif +0 -0
  48. data/generators/surveyor/templates/assets/images/222222_11x11_icon_resize_se.gif +0 -0
  49. data/generators/surveyor/templates/assets/images/222222_35x9_colorpicker_indicator.gif.gif +0 -0
  50. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_down.gif +0 -0
  51. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_left.gif +0 -0
  52. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_right.gif +0 -0
  53. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_up.gif +0 -0
  54. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_leftright.gif +0 -0
  55. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_updown.gif +0 -0
  56. data/generators/surveyor/templates/assets/images/454545_11x11_icon_close.gif +0 -0
  57. data/generators/surveyor/templates/assets/images/454545_11x11_icon_doc.gif +0 -0
  58. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_closed.gif +0 -0
  59. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_open.gif +0 -0
  60. data/generators/surveyor/templates/assets/images/454545_11x11_icon_minus.gif +0 -0
  61. data/generators/surveyor/templates/assets/images/454545_11x11_icon_plus.gif +0 -0
  62. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_down.gif +0 -0
  63. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_left.gif +0 -0
  64. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_right.gif +0 -0
  65. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_up.gif +0 -0
  66. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_leftright.gif +0 -0
  67. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_updown.gif +0 -0
  68. data/generators/surveyor/templates/assets/images/888888_11x11_icon_close.gif +0 -0
  69. data/generators/surveyor/templates/assets/images/888888_11x11_icon_doc.gif +0 -0
  70. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_closed.gif +0 -0
  71. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_open.gif +0 -0
  72. data/generators/surveyor/templates/assets/images/888888_11x11_icon_minus.gif +0 -0
  73. data/generators/surveyor/templates/assets/images/888888_11x11_icon_plus.gif +0 -0
  74. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_down.gif +0 -0
  75. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_left.gif +0 -0
  76. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_right.gif +0 -0
  77. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_up.gif +0 -0
  78. data/generators/surveyor/templates/assets/images/dadada_40x100_textures_02_glass_75.png +0 -0
  79. data/generators/surveyor/templates/assets/images/e6e6e6_40x100_textures_02_glass_75.png +0 -0
  80. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_01_flat_0.png +0 -0
  81. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_02_glass_65.png +0 -0
  82. data/generators/surveyor/templates/assets/javascripts/accessibleUISlider.jQuery.js +201 -0
  83. data/generators/surveyor/templates/assets/javascripts/jquery-1.2.6.js +3549 -0
  84. data/generators/surveyor/templates/assets/javascripts/jquery-ui-personalized-1.5.3.js +7616 -0
  85. data/generators/surveyor/templates/assets/javascripts/jquery.form.js +637 -0
  86. data/generators/surveyor/templates/assets/javascripts/surveyor.js +47 -0
  87. data/generators/surveyor/templates/assets/stylesheets/jquery-ui-slider-additions.css +71 -0
  88. data/generators/surveyor/templates/assets/stylesheets/reset.css +50 -0
  89. data/generators/surveyor/templates/assets/stylesheets/sass/surveyor.sass +243 -0
  90. data/generators/surveyor/templates/assets/stylesheets/surveyor.css +235 -0
  91. data/generators/surveyor/templates/assets/stylesheets/ui.theme.css +851 -0
  92. data/generators/surveyor/templates/initializers/haml.rb +8 -0
  93. data/generators/surveyor/templates/initializers/surveyor.rb +10 -0
  94. data/generators/surveyor/templates/migrate/add_correct_answer_id_to_questions.rb +9 -0
  95. data/generators/surveyor/templates/migrate/add_display_order_to_surveys.rb +9 -0
  96. data/generators/surveyor/templates/migrate/add_index_to_response_sets.rb +9 -0
  97. data/generators/surveyor/templates/migrate/add_index_to_surveys.rb +9 -0
  98. data/generators/surveyor/templates/migrate/add_manual_numbering.rb +11 -0
  99. data/generators/surveyor/templates/migrate/add_unique_indicies.rb +17 -0
  100. data/generators/surveyor/templates/migrate/create_answers.rb +37 -0
  101. data/generators/surveyor/templates/migrate/create_dependencies.rb +22 -0
  102. data/generators/surveyor/templates/migrate/create_dependency_conditions.rb +29 -0
  103. data/generators/surveyor/templates/migrate/create_question_groups.rb +27 -0
  104. data/generators/surveyor/templates/migrate/create_questions.rb +36 -0
  105. data/generators/surveyor/templates/migrate/create_response_sets.rb +22 -0
  106. data/generators/surveyor/templates/migrate/create_responses.rb +33 -0
  107. data/generators/surveyor/templates/migrate/create_survey_sections.rb +29 -0
  108. data/generators/surveyor/templates/migrate/create_surveys.rb +31 -0
  109. data/generators/surveyor/templates/migrate/create_validation_conditions.rb +32 -0
  110. data/generators/surveyor/templates/migrate/create_validations.rb +20 -0
  111. data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +218 -0
  112. data/generators/surveyor/templates/tasks/surveyor.rb +4 -0
  113. data/generators/test_surveyor/templates/TESTING_SURVEYOR +0 -0
  114. data/generators/test_surveyor/templates/environments/cucumber.rb +21 -0
  115. data/generators/test_surveyor/test_surveyor_generator.rb +15 -0
  116. data/jakewendt-surveyor.gemspec +212 -0
  117. data/lib/fixtures_extensions.rb +6 -0
  118. data/lib/jakewendt-surveyor.rb +1 -0
  119. data/lib/surveyor.rb +44 -0
  120. data/lib/surveyor/acts_as_response.rb +33 -0
  121. data/lib/surveyor/config.rb +45 -0
  122. data/lib/tasks/surveyor_tasks.rake +33 -0
  123. data/lib/xml_formatter.rb +12 -0
  124. data/rails/init.rb +1 -0
  125. data/script/surveyor/answer.rb +54 -0
  126. data/script/surveyor/base.rb +77 -0
  127. data/script/surveyor/dependency.rb +13 -0
  128. data/script/surveyor/dependency_condition.rb +40 -0
  129. data/script/surveyor/parser.rb +207 -0
  130. data/script/surveyor/question.rb +37 -0
  131. data/script/surveyor/question_group.rb +26 -0
  132. data/script/surveyor/specs/answer_spec.rb +29 -0
  133. data/script/surveyor/specs/question_spec.rb +63 -0
  134. data/script/surveyor/specs/spec_helper.rb +7 -0
  135. data/script/surveyor/specs/survey_section_spec.rb +23 -0
  136. data/script/surveyor/specs/validation_condition_spec.rb +20 -0
  137. data/script/surveyor/specs/validation_spec.rb +20 -0
  138. data/script/surveyor/survey.rb +35 -0
  139. data/script/surveyor/survey_section.rb +21 -0
  140. data/script/surveyor/validation.rb +21 -0
  141. data/script/surveyor/validation_condition.rb +21 -0
  142. data/script/surveyor/whr_dsl.tmproj +244 -0
  143. data/spec/controllers/surveyor_controller_spec.rb +193 -0
  144. data/spec/factories.rb +145 -0
  145. data/spec/lib/surveyor_spec.rb +44 -0
  146. data/spec/models/answer_spec.rb +29 -0
  147. data/spec/models/dependency_condition_spec.rb +321 -0
  148. data/spec/models/dependency_spec.rb +81 -0
  149. data/spec/models/question_group_spec.rb +35 -0
  150. data/spec/models/question_spec.rb +75 -0
  151. data/spec/models/response_set_spec.rb +245 -0
  152. data/spec/models/response_spec.rb +76 -0
  153. data/spec/models/survey_section_spec.rb +32 -0
  154. data/spec/models/survey_spec.rb +71 -0
  155. data/spec/models/validation_condition_spec.rb +105 -0
  156. data/spec/models/validation_spec.rb +59 -0
  157. data/spec/rcov.opts +2 -0
  158. data/spec/spec.opts +4 -0
  159. data/spec/spec_helper.rb +12 -0
  160. metadata +254 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2009 Brian Chamberlain and Mark Yoon
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,285 @@
1
+ # Survey On Rails
2
+
3
+ Surveyor is a rails (gem) plugin, that brings surveys to your rails app. Before Rails 2.3, it was implemented as a Rails Engine. Surveys are written in a DSL (Domain Specific Language), with examples available in the "kitchen sink" survey.
4
+
5
+ ## Why you might want to use Surveyor
6
+
7
+ If you have to have a part of your Rails app that asks users questions as part of a survey, quiz, or questionnaire then you should consider using Surveyor. This plugin was designed out of the need to deliver clinical research surveys to large populations of people but it can be used for any type of survey. It has an easy to use DSL to define the questions, response dependencies (if user answers 'A' to question 1 then show question 1a, etc...), and structure (different sections of longer questionnaires).
8
+
9
+ To build your questionnaire you define it using a custom DSL. Having a DSL instead of a GUI makes it significantly easier to import long surveys (no more endless clicking and typing into tiny text boxes). It also means that you can let your customer write out the survey, edit, re-edit, tweak, throw out and start over, any number of surveys without having to change a single line of code in your app.
10
+
11
+ ## DSL example
12
+
13
+ Our DSL supports a wide range of question types (too many to list here) and varying dependency logic. Here are the first few questions of the "kitchen_sink" survey which should give you and idea of how the DSL works. The full example with all the types of questions is in the plugin and available if you run the installation instructions below.
14
+
15
+ survey "“Kitchen Sink” survey" do
16
+
17
+ section "Basic questions" do
18
+ # A label is a question that accepts no answers
19
+ label "These questions are examples of the basic supported input types"
20
+
21
+ # A basic question with radio buttons
22
+ question_1 "What is your favorite color?", :pick => :one
23
+ answer "red"
24
+ answer "blue"
25
+ answer "green"
26
+ answer "yellow"
27
+ answer :other
28
+
29
+ # A basic question with checkboxes
30
+ # "question" and "answer" may be abbreviated as "q" and "a"
31
+ q_2 "Choose the colors you don't like", :pick => :any
32
+ a_1 "red"
33
+ a_2 "blue"
34
+ a_3 "green"
35
+ a_4 "yellow"
36
+ a :omit
37
+
38
+ # A dependent question, with conditions and rule to logically join them
39
+ # the question's reference identifier is "2a", and the answer's reference_identifier is "1"
40
+ # question reference identifiers used in conditions need to be unique on a survey for the lookups to work
41
+ q_2a "Please explain why you don't like this color?"
42
+ a_1 "explanation", :text
43
+ dependency :rule => "A or B or C or D"
44
+ condition_A :q_2, "==", :a_1
45
+ condition_B :q_2, "==", :a_2
46
+ condition_C :q_2, "==", :a_3
47
+ condition_D :q_2, "==", :a_4
48
+
49
+ # ... other question, sections and such. See kitchen_sink_survey.rb for more.
50
+ end
51
+
52
+ end
53
+
54
+ The survey above shows a couple simple question types. The first one is a "pick one" type with the "other" custom entry. The second question is a "pick any" type with the option to "omit". It also has a dependency where you can ask a follow up question based on how the user answered the previous question. Notice the way the dependency is defined as a string. This implementation supports any number of complex dependency rules so not just "A or B or C or D" but "A and (B or C) and D" or "!A or ((B and !C) or D)". The conditions are the letters used they are evaluated separately using the operators defined for "==","<>", ">=","<", (the usual stuff) the plugged in to the dependency rule and evaluated. See the example survey for more details.
55
+
56
+ # Installation
57
+
58
+ As a plugin:
59
+
60
+ gem install haml
61
+ script/plugin install git://github.com/breakpointer/surveyor.git -r 'tag v0.10.0'
62
+
63
+ Or as a gem plugin:
64
+
65
+ # in environment.rb
66
+ config.gem "surveyor", :version => '~> 0.10.0', :source => 'http://gemcutter.org'
67
+
68
+ rake gems:install
69
+
70
+ Generate assets, run migrations:
71
+
72
+ script/generate surveyor
73
+ rake db:migrate
74
+
75
+ Try out the "kitchen sink" survey:
76
+
77
+ rake surveyor FILE=surveys/kitchen_sink_survey.rb
78
+
79
+ The rake surveyor task overwrites previous surveys by default, but can append instead:
80
+
81
+ rake surveyor FILE=surveys/kitchen_sink_survey.rb APPEND=true
82
+
83
+ The rake tasks above generate surveys in our custom survey DSL (which is a great format for end users and stakeholders to use).
84
+ After you have run them start up your app:
85
+
86
+ script/server
87
+
88
+ (or however you normally start your app) and goto:
89
+
90
+ http://localhost:3000/surveys
91
+
92
+ Try taking the survey and compare it to the contents of the DSL file kitchen\_sink\_survey.rb. See how each type of
93
+ DSL question maps to the resulting rendered view of the question.
94
+
95
+ # Configuration
96
+
97
+ The surveyor generator creates config/initializers/surveyor.rb. There, you can specify:
98
+
99
+ - your own relative root for surveys ('/' is not recommended as any path will be interpreted as a survey name)
100
+ - your own custom title (string) for the survey list page
101
+ - your own custom layout file name, in your app/views/layouts folder
102
+ - your own custom finish url for all surveys. you can give a string (a path), a symbol (the name of a method in ApplicationController)
103
+ - if you would like surveys to require authorization via the restful_authentication plugin
104
+ - if you would like to extend the surveyor_controller (see Extending Surveyor below)
105
+
106
+ The initializer runs once, when the app starts. The block style is used to keep multiple options DRY (defaults below):
107
+
108
+ Surveyor::Config.run do |config|
109
+ config['default.relative_url_root'] = nil # "surveys"
110
+ config['default.title'] = nil # "You can take these surveys:"
111
+ config['default.layout'] = nil # "surveyor_default"
112
+ config['default.index'] = nil # "/surveys" # or :index_path_method
113
+ config['default.finish'] = nil # "/surveys" # or :finish_path_method
114
+ #config['authentication_method'] = :login_required # set to true to use restful authentication
115
+ config['extend'] = %w() # %w(survey surveyor_helper surveyor_controller)
116
+ end
117
+
118
+ You can update surveyor's configuration at any time. Use the block style (above), or the individual style:
119
+
120
+ Surveyor::Config['default.title'] = "Cheese is great!"
121
+
122
+ To look at the current surveyor configuration:
123
+
124
+ Surveyor::Config.to_hash.inspect
125
+
126
+ # Extending surveyor
127
+
128
+ Surveyor's models, helper, and controller can be extended from custom modules your app/models, app/helpers and app/controllers directories. To generate the sample files and sample layout, run:
129
+
130
+ script/generate extend_surveyor
131
+
132
+ Any of surveyor's models class_eval, class methods, and instance methods can be modified. Include the following in config/initializers/surveyor.rb:
133
+
134
+ require 'models/survey_extensions' # Extended the survey model
135
+
136
+ SurveyorHelper class_eval and instance methods can be modified. Include the following in config/initializers/surveyor.rb:
137
+
138
+ require 'helpers/surveyor_helper_extensions' # Extend the surveyor helper
139
+
140
+ SurveyorController class_eval, class methods, instance methods, and actions can be modified. Action methods should be specified separately in the Actions submodule. Set the following option in config/initializers/surveyor.rb Surveyor::Config block:
141
+
142
+ config['extend_controller'] = true
143
+
144
+ # Sample layout
145
+
146
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
147
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
148
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
149
+ <head>
150
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
151
+ <title>Survey: <%= controller.action_name %></title>
152
+ <%= surveyor_includes %>
153
+ </head>
154
+ <body>
155
+ <div id="flash"><%= flash[:notice] %></div>
156
+ <%= yield %>
157
+ </body>
158
+ </html>
159
+
160
+ The <code>surveyor\_includes</code> helper just calls <code>surveyor\_stylsheets + surveyor\_javascripts</code> which in turn call:
161
+
162
+ stylesheet_link_tag 'surveyor/reset', 'surveyor/surveyor', 'surveyor/ui.theme.css','surveyor/jquery-ui-slider-additions'
163
+
164
+ javascript_include_tag 'surveyor/jquery-1.2.6.js', 'surveyor/jquery-ui-personalized-1.5.3.js', 'surveyor/accessibleUISlider.jQuery.js','surveyor/jquery.form.js', 'surveyor/surveyor.js'
165
+
166
+ # Dependencices
167
+
168
+ Surveyor depends on Rails 2.3 and the SASS style sheet language, part of HAML (http://haml.hamptoncatlin.com/download). For running the test suite you will need rspec and have the rspec plugin installed in your application.
169
+
170
+ # Test Suite and Development
171
+
172
+ To work on the plugin code (for enhancements, and bug fixes, etc...) fork this github project. Then clone the project under the vendor/plugins directory in a Rails app used only for development:
173
+
174
+
175
+ # Changes
176
+
177
+ 0.11.0
178
+
179
+ * basic csv export. closes #21
180
+ * add unique indicies. closes #45
181
+ * add one_integer renderer. closes #51
182
+ * constrain surveys to have unique access_codes. closes #45. closes #42
183
+ * covering the extremely unlikely case that response_sets may have a non-unique access_code. closes #46. thanks jakewendt.
184
+ * current user id not needed in the view, set in SurveyorController. closes #48. thanks jakewendt
185
+
186
+ 0.10.0
187
+
188
+ * surveyor config['extend'] is now an array. custom modules (e.g. SurveyExtensions are now included from within surveyor models, allowing
189
+ the customizations to work on every request in development. closes #39. thanks to mgurley and jakewendt for the suggestions.
190
+ * remove comment from surveyor_includes
191
+ * css tweak
192
+ * automatically add backslashes and eliminate multiple backslashes in relative root for routes
193
+ * readme spelling and line breaks
194
+ * fixing a failing spec with factory instead of mock parent model
195
+ * upgrading cucumber to 0.6
196
+
197
+ 0.9.11
198
+
199
+ * adding rails init.rb to make gem loading work. thanks mike gurley. closes #52.
200
+ * Repeater changed to only have +1, not +3 as previous
201
+ * added locking and transaction to surveyor update action. Prevents bug that caused duplicated answers
202
+ * some light re-factoring and code readability changes
203
+ * some code formatting changes
204
+ * added require statement to specs so the factory_girl test dependency was more clear
205
+ * spiced up the readme... may have some typos
206
+ * readme update
207
+
208
+ 0.9.10
209
+
210
+ * styles, adding labels for dates, correcting labels for radio buttons
211
+
212
+ 0.9.9
213
+
214
+ * count label and image questions complete when mandatory. closes #38
215
+ * validate by other responses. closes #35
216
+
217
+ 0.9.8
218
+
219
+ * @current\_user.id if @current\_user isn't nil. Closes #37
220
+
221
+ 0.9.7
222
+
223
+ * fixing typos
224
+ * remove surveyor controller from load\_once\_paths. fixes issue with dependencies and unloading in development. closes #36
225
+
226
+ 0.9.6
227
+
228
+ * response set reports progress and mandatory questions completeness. closes #33
229
+ * adding correctness to response sets
230
+ * adding correctness to responses
231
+
232
+ 0.9.5
233
+
234
+ * allow append for survey parser. closes #32
235
+
236
+ 0.9.4
237
+
238
+ * making tinycode compatible with ruby 1.8.6
239
+
240
+ 0.9.3
241
+
242
+ * fix for survey parser require
243
+
244
+ 0.9.2
245
+
246
+ * fixing specs for namespacing and move of tinycode
247
+ * namespacing SurveyParser models to avoid conflict with model extensions
248
+
249
+ 0.9.1
250
+
251
+ * fix for tinycode, more descriptive missing method
252
+
253
+ 0.9.0
254
+
255
+ * validations in dsl and surveyor models
256
+ * preserve underscores in reference identifiers
257
+ * dsl specs, refactoring into base class
258
+ * adding display order to surveys
259
+ * moving columnizer and tiny column functionality to surveyor module
260
+ * columnizer (and tiny code) refactoring, columnizer spec extracted from answer spec
261
+ * cleanup of scopes with joins
262
+ * refactoring dependency
263
+
264
+ 0.8.0
265
+
266
+ * question group dependencies
267
+ * expanded examples in kitchen sink survey
268
+ * specs
269
+
270
+ 0.7.1
271
+
272
+ * custom index page
273
+ * custom classes and renderers
274
+ * fixing typo in kitchen sink survey
275
+
276
+ 0.7.0
277
+
278
+ * new kitchen sink survey with better documentation of DSL
279
+ * migration misspelling
280
+ * fixing ordering, dependency conditions evaluation, and changing named scopes for now
281
+ * DRYing up surveyor DSL models
282
+ * working on adding dependencies for question groups
283
+
284
+
285
+ Copyright (c) 2008-2009 Brian Chamberlain and Mark Yoon, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "jakewendt-surveyor"
8
+ gem.summary = %Q{A rails (gem) plugin to enable surveys in your application}
9
+ gem.email = "github@jake.otherinbox.com"
10
+ gem.homepage = "http://github.com/jakewendt/surveyor"
11
+ gem.authors = ["Brian Chamberlain", "Mark Yoon",'Jake Wendt']
12
+ gem.add_dependency 'haml'
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ begin
22
+ require 'spec/rake/spectask'
23
+ Spec::Rake::SpecTask.new(:spec) do |spec|
24
+ spec.libs << 'lib' << 'spec'
25
+ spec.spec_files = FileList['spec/**/*_spec.rb']
26
+ end
27
+
28
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.pattern = 'spec/**/*_spec.rb'
31
+ spec.rcov = true
32
+ end
33
+ rescue LoadError
34
+ puts "RSpec is not available. In order to run those tasks, you must: sudo gem install rspec"
35
+ end
36
+
37
+
38
+ task :default => :spec
39
+
40
+ require 'rake/rdoctask'
41
+ Rake::RDocTask.new do |rdoc|
42
+ if File.exist?('VERSION.yml')
43
+ config = YAML.load(File.read('VERSION.yml'))
44
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
45
+ else
46
+ version = ""
47
+ end
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "surveyor #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
54
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.11.3
@@ -0,0 +1,142 @@
1
+ # The Surveyor controller a user taking a survey. It is semi-RESTful since it does not have a concrete representation model.
2
+ # The "resource" is a survey attempt/session populating a response set.
3
+
4
+ class SurveyorController < ApplicationController
5
+
6
+ # Layout
7
+ layout Surveyor::Config['default.layout'] || 'surveyor_default'
8
+
9
+ # Extending surveyor
10
+ include SurveyorControllerExtensions if Surveyor::Config['extend'].include?("surveyor_controller")
11
+ before_filter :extend_actions
12
+
13
+ # RESTful authentication
14
+ if Surveyor::Config['authentication_method']
15
+ before_filter Surveyor::Config['authentication_method']
16
+ end
17
+
18
+ # Get the response set or current_user
19
+ # before_filter :get_response_set, :except => [:new, :create]
20
+ before_filter :get_current_user, :only => [:new, :create]
21
+
22
+ # Actions
23
+ def new
24
+ @surveys = Survey.find(:all)
25
+ redirect_to surveyor_default(:index) unless available_surveys_path == surveyor_default(:index)
26
+ end
27
+
28
+ def create
29
+ @survey = Survey.find_by_access_code(params[:survey_code])
30
+ @response_set = ResponseSet.create(:survey => @survey, :user_id => (@current_user.nil? ? @current_user : @current_user.id))
31
+ if (@survey && @response_set)
32
+ flash[:notice] = "Survey was successfully started."
33
+ redirect_to(edit_my_survey_path(:survey_code => @survey.access_code, :response_set_code => @response_set.access_code))
34
+ else
35
+ flash[:notice] = "Unable to find that survey"
36
+ redirect_to(available_surveys_path)
37
+ end
38
+ end
39
+
40
+ def show
41
+ @response_set = ResponseSet.find_by_access_code(params[:response_set_code], :include => {:responses => [:question, :answer]})
42
+ respond_to do |format|
43
+ format.html #{render :action => :show}
44
+ format.csv {
45
+ send_data(@response_set.to_csv, :type => 'text/csv; charset=utf-8; header=present',:filename => "#{@response_set.updated_at.strftime('%Y-%m-%d')}_#{@response_set.access_code}.csv")
46
+ }
47
+ end
48
+ end
49
+
50
+ def edit
51
+ @response_set = ResponseSet.find_by_access_code(params[:response_set_code], :include => {:responses => [:question, :answer]})
52
+ if @response_set
53
+ @survey = Survey.with_sections.find_by_id(@response_set.survey_id)
54
+ @sections = @survey.sections
55
+ if params[:section]
56
+ @section = @sections.with_includes.find(section_id_from(params[:section])) || @sections.with_includes.first
57
+ else
58
+ @section = @sections.with_includes.first
59
+ end
60
+ @questions = @section.questions
61
+ @dependents = (@response_set.unanswered_dependencies - @section.questions) || []
62
+ else
63
+ flash[:notice] = "Unable to find your responses to the survey"
64
+ redirect_to(available_surveys_path)
65
+ end
66
+ end
67
+
68
+ def update
69
+ saved = nil
70
+ ActiveRecord::Base.transaction do
71
+ if @response_set = ResponseSet.find_by_access_code(params[:response_set_code], :include => {:responses => :answer},:lock => true)
72
+ @response_set.current_section_id = params[:current_section_id]
73
+ else
74
+ flash[:notice] = "Unable to find your responses to the survey"
75
+ redirect_to(available_surveys_path) and return
76
+ end
77
+
78
+ if params[:responses] or params[:response_groups]
79
+ @response_set.clear_responses
80
+ saved = @response_set.update_attributes(:response_attributes => (params[:responses] || {}).dup ,
81
+ :response_group_attributes => (params[:response_groups] || {}).dup) #copy (dup) to preserve params because we manipulate params in the response_set methods
82
+ if (saved && params[:finish])
83
+ @response_set.complete!
84
+ saved = @response_set.save!
85
+ end
86
+ end
87
+ end
88
+ respond_to do |format|
89
+ format.html do
90
+ if saved && params[:finish]
91
+ flash[:notice] = "Completed survey"
92
+ redirect_to surveyor_default(:finish)
93
+ else
94
+ flash[:notice] = "Unable to update survey" if !saved #and !saved.nil? # saved.nil? is true if there are no questions on the page (i.e. if it only contains a label)
95
+ redirect_to :action => "edit", :anchor => anchor_from(params[:section]), :params => {:section => section_id_from(params[:section])}
96
+ end
97
+ end
98
+ # No redirect needed if we're talking to the page via json
99
+ format.js do
100
+ # render :json => @response_set.all_dependencies.to_json
101
+ render :json => @response_set.all_things_hash.to_json
102
+ end
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ # Filters
109
+ def get_current_user
110
+ @current_user = self.respond_to?(:current_user) ? self.current_user : nil
111
+ end
112
+
113
+ # Params: the name of some submit buttons store the section we'd like to go to. for repeater questions, an anchor to the repeater group is also stored
114
+ # e.g. params[:section] = {"1"=>{"question_group_1"=>"<= add row"}}
115
+ def section_id_from(p)
116
+ p.respond_to?(:keys) ? p.keys.first : p
117
+ end
118
+
119
+ def anchor_from(p)
120
+ p.respond_to?(:keys) && p[p.keys.first].respond_to?(:keys) ? p[p.keys.first].keys.first : nil
121
+ end
122
+
123
+ # Extending surveyor
124
+ def surveyor_default(type = :finish)
125
+ # http://www.postal-code.com/mrhappy/blog/2007/02/01/ruby-comparing-an-objects-class-in-a-case-statement/
126
+ # http://www.skorks.com/2009/08/how-a-ruby-case-statement-works-and-what-you-can-do-with-it/
127
+ case arg = Surveyor::Config["default.#{type.to_s}"]
128
+ when String
129
+ return arg
130
+ when Symbol
131
+ return self.send(arg)
132
+ else
133
+ return available_surveys_path
134
+ end
135
+ end
136
+
137
+ def extend_actions
138
+ # http://blog.mattwynne.net/2009/07/11/rails-tip-use-polymorphism-to-extend-your-controllers-at-runtime/
139
+ self.extend SurveyorControllerExtensions::Actions if Surveyor::Config['extend'].include?("surveyor_controller") && defined? SurveyorControllerExtensions::Actions
140
+ end
141
+
142
+ end