surveyor 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. data/.gitignore +6 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +104 -0
  4. data/Rakefile +50 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/surveyor_controller.rb +117 -0
  7. data/app/helpers/survey_form_builder.rb +37 -0
  8. data/app/helpers/surveyor_helper.rb +66 -0
  9. data/app/models/answer.rb +21 -0
  10. data/app/models/dependency.rb +46 -0
  11. data/app/models/dependency_condition.rb +79 -0
  12. data/app/models/question.rb +54 -0
  13. data/app/models/question_group.rb +18 -0
  14. data/app/models/response.rb +47 -0
  15. data/app/models/response_set.rb +185 -0
  16. data/app/models/survey.rb +57 -0
  17. data/app/models/survey_section.rb +15 -0
  18. data/app/views/layouts/surveyor_default.html.erb +13 -0
  19. data/app/views/partials/_answer.html.haml +49 -0
  20. data/app/views/partials/_question.html.haml +73 -0
  21. data/app/views/partials/_question_group.html.haml +41 -0
  22. data/app/views/surveyor/edit.html.haml +32 -0
  23. data/app/views/surveyor/new.html.haml +17 -0
  24. data/app/views/surveyor/show.html.haml +12 -0
  25. data/config/routes.rb +10 -0
  26. data/generators/surveyor/EXTENDING_SURVEYOR +12 -0
  27. data/generators/surveyor/extend_surveyor_generator.rb +22 -0
  28. data/generators/surveyor/surveyor_generator.rb +60 -0
  29. data/generators/surveyor/templates/README +10 -0
  30. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_leftright.gif +0 -0
  31. data/generators/surveyor/templates/assets/images/222222_11x11_icon_arrows_updown.gif +0 -0
  32. data/generators/surveyor/templates/assets/images/222222_11x11_icon_close.gif +0 -0
  33. data/generators/surveyor/templates/assets/images/222222_11x11_icon_doc.gif +0 -0
  34. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_closed.gif +0 -0
  35. data/generators/surveyor/templates/assets/images/222222_11x11_icon_folder_open.gif +0 -0
  36. data/generators/surveyor/templates/assets/images/222222_11x11_icon_minus.gif +0 -0
  37. data/generators/surveyor/templates/assets/images/222222_11x11_icon_plus.gif +0 -0
  38. data/generators/surveyor/templates/assets/images/222222_11x11_icon_resize_se.gif +0 -0
  39. data/generators/surveyor/templates/assets/images/222222_35x9_colorpicker_indicator.gif.gif +0 -0
  40. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_down.gif +0 -0
  41. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_left.gif +0 -0
  42. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_right.gif +0 -0
  43. data/generators/surveyor/templates/assets/images/222222_7x7_arrow_up.gif +0 -0
  44. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_leftright.gif +0 -0
  45. data/generators/surveyor/templates/assets/images/454545_11x11_icon_arrows_updown.gif +0 -0
  46. data/generators/surveyor/templates/assets/images/454545_11x11_icon_close.gif +0 -0
  47. data/generators/surveyor/templates/assets/images/454545_11x11_icon_doc.gif +0 -0
  48. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_closed.gif +0 -0
  49. data/generators/surveyor/templates/assets/images/454545_11x11_icon_folder_open.gif +0 -0
  50. data/generators/surveyor/templates/assets/images/454545_11x11_icon_minus.gif +0 -0
  51. data/generators/surveyor/templates/assets/images/454545_11x11_icon_plus.gif +0 -0
  52. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_down.gif +0 -0
  53. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_left.gif +0 -0
  54. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_right.gif +0 -0
  55. data/generators/surveyor/templates/assets/images/454545_7x7_arrow_up.gif +0 -0
  56. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_leftright.gif +0 -0
  57. data/generators/surveyor/templates/assets/images/888888_11x11_icon_arrows_updown.gif +0 -0
  58. data/generators/surveyor/templates/assets/images/888888_11x11_icon_close.gif +0 -0
  59. data/generators/surveyor/templates/assets/images/888888_11x11_icon_doc.gif +0 -0
  60. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_closed.gif +0 -0
  61. data/generators/surveyor/templates/assets/images/888888_11x11_icon_folder_open.gif +0 -0
  62. data/generators/surveyor/templates/assets/images/888888_11x11_icon_minus.gif +0 -0
  63. data/generators/surveyor/templates/assets/images/888888_11x11_icon_plus.gif +0 -0
  64. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_down.gif +0 -0
  65. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_left.gif +0 -0
  66. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_right.gif +0 -0
  67. data/generators/surveyor/templates/assets/images/888888_7x7_arrow_up.gif +0 -0
  68. data/generators/surveyor/templates/assets/images/dadada_40x100_textures_02_glass_75.png +0 -0
  69. data/generators/surveyor/templates/assets/images/e6e6e6_40x100_textures_02_glass_75.png +0 -0
  70. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_01_flat_0.png +0 -0
  71. data/generators/surveyor/templates/assets/images/ffffff_40x100_textures_02_glass_65.png +0 -0
  72. data/generators/surveyor/templates/assets/javascripts/accessibleUISlider.jQuery.js +201 -0
  73. data/generators/surveyor/templates/assets/javascripts/jquery-1.2.6.js +3549 -0
  74. data/generators/surveyor/templates/assets/javascripts/jquery-ui-personalized-1.5.3.js +7616 -0
  75. data/generators/surveyor/templates/assets/javascripts/jquery.form.js +637 -0
  76. data/generators/surveyor/templates/assets/javascripts/surveyor.js +28 -0
  77. data/generators/surveyor/templates/assets/stylesheets/jquery-ui-slider-additions.css +71 -0
  78. data/generators/surveyor/templates/assets/stylesheets/reset.css +46 -0
  79. data/generators/surveyor/templates/assets/stylesheets/sass/surveyor.sass +245 -0
  80. data/generators/surveyor/templates/assets/stylesheets/surveyor.css +231 -0
  81. data/generators/surveyor/templates/assets/stylesheets/ui.theme.css +851 -0
  82. data/generators/surveyor/templates/extensions/survey_extensions.rb +18 -0
  83. data/generators/surveyor/templates/extensions/surveyor_controller_extensions.rb +28 -0
  84. data/generators/surveyor/templates/extensions/surveyor_custom.html.erb +13 -0
  85. data/generators/surveyor/templates/extensions/surveyor_helper_extensions.rb +18 -0
  86. data/generators/surveyor/templates/initializers/haml.rb +8 -0
  87. data/generators/surveyor/templates/initializers/surveyor.rb +11 -0
  88. data/generators/surveyor/templates/migrate/create_answers.rb +45 -0
  89. data/generators/surveyor/templates/migrate/create_dependencies.rb +21 -0
  90. data/generators/surveyor/templates/migrate/create_dependency_conditions.rb +29 -0
  91. data/generators/surveyor/templates/migrate/create_question_groups.rb +18 -0
  92. data/generators/surveyor/templates/migrate/create_questions.rb +33 -0
  93. data/generators/surveyor/templates/migrate/create_response_sets.rb +22 -0
  94. data/generators/surveyor/templates/migrate/create_responses.rb +33 -0
  95. data/generators/surveyor/templates/migrate/create_survey_sections.rb +25 -0
  96. data/generators/surveyor/templates/migrate/create_surveys.rb +25 -0
  97. data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +201 -0
  98. data/generators/surveyor/templates/tasks/surveyor.rb +4 -0
  99. data/init.rb +1 -0
  100. data/install.rb +1 -0
  101. data/lib/surveyor.rb +7 -0
  102. data/lib/surveyor/config.rb +45 -0
  103. data/lib/tasks/surveyor_tasks.rake +33 -0
  104. data/lib/tiny_code.rb +58 -0
  105. data/lib/xml_formatter.rb +12 -0
  106. data/script/surveyor/answer.rb +84 -0
  107. data/script/surveyor/columnizer.rb +36 -0
  108. data/script/surveyor/dependency.rb +43 -0
  109. data/script/surveyor/dependency_condition.rb +74 -0
  110. data/script/surveyor/question.rb +76 -0
  111. data/script/surveyor/question_group.rb +33 -0
  112. data/script/surveyor/specs/answer_spec.rb +66 -0
  113. data/script/surveyor/specs/question_dependency_spec.rb +46 -0
  114. data/script/surveyor/specs/question_group_spec.rb +9 -0
  115. data/script/surveyor/specs/question_spec.rb +111 -0
  116. data/script/surveyor/specs/section_spec.rb +58 -0
  117. data/script/surveyor/survey.rb +108 -0
  118. data/script/surveyor/survey_parser.rb +64 -0
  119. data/script/surveyor/survey_section.rb +153 -0
  120. data/script/surveyor/whr_dsl.tmproj +244 -0
  121. data/spec/controllers/surveyor_controller_spec.rb +328 -0
  122. data/spec/factories.rb +107 -0
  123. data/spec/models/answer_spec.rb +29 -0
  124. data/spec/models/dependency_condition_spec.rb +338 -0
  125. data/spec/models/dependency_spec.rb +82 -0
  126. data/spec/models/question_group_spec.rb +11 -0
  127. data/spec/models/question_spec.rb +75 -0
  128. data/spec/models/response_set_spec.rb +153 -0
  129. data/spec/models/response_spec.rb +94 -0
  130. data/spec/models/survey_section_spec.rb +34 -0
  131. data/spec/models/survey_spec.rb +72 -0
  132. data/spec/rcov.opts +2 -0
  133. data/spec/spec.opts +4 -0
  134. data/spec/spec_helper.rb +14 -0
  135. data/surveyor.gemspec +187 -0
  136. data/uninstall.rb +1 -0
  137. metadata +211 -0
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
6
+ <title>Survey: <%= controller.action_name %></title>
7
+ <%= surveyor_includes %>
8
+ </head>
9
+ <body>
10
+ <div id="flash"><%= flash[:notice] %></div>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1,49 @@
1
+ - renderer = answer.renderer(question)
2
+ - hide_label ||= false
3
+ - disabled ||= false
4
+
5
+ - fields_for_response(response_obj) do |response_form|
6
+ - case renderer
7
+ - when :any_answer
8
+ = response_form.survey_check_box(:selected)
9
+ = response_form.label("selected", answer.text) unless hide_label # This is a temp fix til I figure out why the id of the checkbox is all jacked up
10
+ - when :any_other_and_string
11
+ = response_form.survey_check_box(:selected)
12
+ %label Other
13
+ = response_form.text_field(:other_value)
14
+ = response_form.text_field(:string_value)
15
+ - when :any_string
16
+ = response_form.survey_check_box(:selected)
17
+ = response_form.label(:answer_id, answer.text)
18
+ = response_form.text_field(:string_value, :size => 25, :maxlength => 250)
19
+ - when :one_answer, :one_string
20
+ - fields_for_radio(response_obj) do |radio_form|
21
+ = radio_form.radio_button(:answer_id, answer.id, :checked => response_obj.selected?)
22
+ = radio_form.label("answer_#{answer.id}", answer.text) unless hide_label
23
+ - if renderer == :one_string
24
+ = response_form.text_field(:string_value, :size => 25, :maxlength => 250, :autocomplete => "off")
25
+ - when :none_date
26
+ = response_form.text_field(:datetime_value, {:include_blank => true})
27
+ - when :none_datetime
28
+ = response_form.datetime_select(:datetime_value, {:include_blank => true})
29
+ - when :none_float
30
+ = response_form.label(:float_value, split_text(answer.text)[:prefix]) unless hide_label
31
+ = response_form.text_field(:float_value, :size => 5, :maxlength => 10, :autocomplete => "off")
32
+ = response_form.label(:float_value, split_text(answer.text)[:postfix]) unless hide_label
33
+ - when :none_integer
34
+ = response_form.label(:integer_value, split_text(answer.text)[:prefix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
35
+ = response_form.text_field(:integer_value, :size => 5, :maxlength => 10, :autocomplete => "off", :disabled => disabled)
36
+ = response_form.label(:integer_value, split_text(answer.text)[:postfix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
37
+ - when :none_string
38
+ = response_form.label(:string_value, split_text(answer.text)[:prefix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
39
+ = response_form.text_field(:string_value, :size => 25, :maxlength => 250, :autocomplete => "off", :disabled => disabled)
40
+ = response_form.label(:string_value, split_text(answer.text)[:postfix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
41
+ - when :none_text
42
+ = response_form.label(:text_value, split_text(answer.text)[:prefix]) unless hide_label
43
+ = response_form.text_area(:text_value, :cols => 80, :rows => 10)
44
+ = response_form.label(:text_value, split_text(answer.text)[:postfix]) unless hide_label
45
+ - when :none_time
46
+ = response_form.time_select(:datetime_value,{ :include_blank => true })
47
+ - else
48
+ = answer.text
49
+
@@ -0,0 +1,73 @@
1
+ - renderer = question.renderer(question_group ||= nil)
2
+ - dep_class = question.dep_class(response_set)
3
+
4
+ - case renderer
5
+ - when :label
6
+ - div_for question, :class => "label #{dep_class}" do
7
+ %span.text= question.text
8
+ %span.help= question.help_text
9
+ - when :image
10
+ .image= image_tag(question.text)
11
+ - when :dropdown, :slider
12
+ - if renderer == :slider
13
+ %script{:type => "text/javascript"}= "$(function(){$('#slider_#{question.id}').accessibleUISlider({width: 400, labels:#{question.answers.size} }).hide();});"
14
+ - div_for question, :class => dep_class do
15
+ .number= next_number unless question.dependent?
16
+ %fieldset
17
+ %legend{:style => "display:inline;"}
18
+ %span.text= question.text
19
+ %span.help= question.help_text
20
+ = hidden_field_tag("responses[#{question.id}][question_id]", question.id)
21
+ %ol.answers
22
+ %li.answer
23
+ - options = question.answers.collect{|a| "<option #{ (response_set.response_for(question.id, a.id).selected?)? "selected='selected'" : nil } value ='#{a.id}'>#{a.text}</option>" }
24
+ = renderer == :slider ? select_tag("responses[#{question.id}][answer_id]", options, {:id => "slider_#{question.id}"}) : select_tag("responses[#{question.id}][answer_id]", ["<option value=''>Select one...</option>"].concat(options))
25
+ - when :grid_default
26
+ - reset_cycle("col")
27
+ - content_tag_for :tr, question, :class => dep_class do
28
+ %td.question_prefix
29
+ %span.text= split_text(question.text)[:prefix]
30
+ %span.help= question.help_text
31
+ = hidden_field_tag("responses[#{question.id}][question_id]", question.id)
32
+ - question.answers.each do |answer|
33
+ %td{:class => "#{cycle("column_highlight", "", :name => "col")}"}
34
+ .answer= render(:partial => "/partials/answer", :locals => {:answer => answer, :question => question, :response_obj => @response_set.response_for(question.id, answer.id), :hide_label => true})
35
+ %td.question_postfix
36
+ %span.text= split_text(question.text)[:postfix]
37
+ - when :repeater_default, :repeater_dropdown
38
+ - disabled ||= false
39
+ - div_for question, :class => "#{disabled ? 'dis' : 'en'}abled #{dep_class}" do
40
+ %span.text= question.text
41
+ %span.help= question.help_text
42
+ = hidden_field_tag("response_groups[#{question.id}][#{response_group}][response_group]", response_group)
43
+ = hidden_field_tag("response_groups[#{question.id}][#{response_group}][question_id]", question.id)
44
+ %ol.answers
45
+ - if renderer == :repeater_default
46
+ - question.answers.each do |answer|
47
+ - content_tag_for :li, answer do
48
+ = render(:partial => "/partials/answer", :locals => {:answer => answer, :question => question, :response_obj => @response_set.response_for(question.id, answer.id), :response_group => response_group, :hide_label => true, :disabled => disabled})
49
+ - else
50
+ %li.answer
51
+ - options = question.answers.collect{|a| "<option #{ (response_set.response_for(question.id, a.id).selected?)? "selected='selected'" : nil } value ='#{a.id}'>#{a.text}</option>" }
52
+ = select_tag("responses[#{question.id}][answer_id]", ["<option value=''>Select one...</option>"].concat(options))
53
+ - when :inline_default, :inline_dropdown
54
+ - div_for question, :class => "inline #{dep_class}" do
55
+ = hidden_field_tag("responses[#{question.id}][question_id]", question.id)
56
+ - if renderer == :inline_default
57
+ - question.answers.each do |answer|
58
+ .answer= render(:partial => "/partials/answer", :locals => {:answer => answer, :question => question, :response_obj => @response_set.response_for(question.id, answer.id), :hide_label => answer.hide_label})
59
+ - else
60
+ - options = question.answers.collect{|a| "<option #{ (response_set.response_for(question.id, a.id).selected?)? "selected='selected'" : nil } value ='#{a.id}'>#{a.text}</option>" }
61
+ = select_tag("responses[#{question.id}][answer_id]", ["<option value=''>Select one...</option>"].concat(options))
62
+ - else # :default, :inline
63
+ - div_for question, :class => dep_class do
64
+ .number= next_number unless question.dependent?
65
+ %fieldset
66
+ %legend
67
+ %span.text= question.text
68
+ %span.help= question.help_text
69
+ = hidden_field_tag("responses[#{question.id}][question_id]", question.id)
70
+ %ol.answers{:class => renderer == :inline ? "inline" : nil}
71
+ - question.answers.each do |answer|
72
+ - content_tag_for :li, answer do
73
+ = render(:partial => "/partials/answer", :locals => {:answer => answer, :question => question, :response_obj => @response_set.response_for(question.id, answer.id), :hide_label => answer.hide_label})
@@ -0,0 +1,41 @@
1
+ - renderer = question_group.renderer
2
+ - locals = {:question_group => question_group, :response_set => response_set, :hide_label => true}
3
+
4
+ - div_for question_group do
5
+ .head
6
+ .number= next_number
7
+ %span.text= question_group.text
8
+ %span.help= question_group.help_text
9
+
10
+ - case question_group.renderer
11
+ - when :grid
12
+ %table.grid
13
+ %thead
14
+ %tr
15
+ %th= "&nbsp;"
16
+ - reset_cycle("column_highlight")
17
+ - group_questions.first.answers.each do |answer|
18
+ %th{:class => "#{cycle("column_highlight", "", :name => "column_highlight")}"}= answer.text
19
+ %tfoot
20
+ %tr
21
+ %th= "&nbsp;"
22
+ - reset_cycle("column_highlight")
23
+ - group_questions.first.answers.each do |answer|
24
+ %th{:class => "#{cycle("column_highlight","", :name => "column_highlight")}"}= answer.text
25
+ %tbody
26
+ - group_questions.each do |question|
27
+ = render(:partial => "/partials/question", :locals => locals.merge({:question => question}))
28
+ - when :repeater
29
+ %ul.repeater
30
+ - (response_set.count_group_responses(group_questions) + 1).times do |group_number|
31
+ %li.repeater
32
+ - group_questions.each do |question|
33
+ = render(:partial => "/partials/question", :locals => locals.merge({:question => question, :response_group => group_number, :disabled => false}))
34
+ %li.repeater
35
+ - group_questions.each do |question|
36
+ = render(:partial => "/partials/question", :locals => locals.merge({:question => question, :response_group => 9999, :disabled => true}))
37
+ = submit_tag("&lt;= add row", :name => "section[#{group_questions.first.survey_section_id}]question_group_#{question_group.id}", :class => "add_row")
38
+ - else # :inline
39
+ %ul
40
+ - group_questions.each do |question|
41
+ %li{:class => question_group.renderer == :inline ? "inline" : nil}= render(:partial => "/partials/question", :locals => locals.merge({:question => question}))
@@ -0,0 +1,32 @@
1
+ #surveyor
2
+ - form_tag(update_my_survey_path, :method => :put, :id => "survey_form") do
3
+ = hidden_field_tag :current_section_id, @section.id
4
+ - unless @sections.size < 3
5
+ #menu
6
+ Sections:
7
+ %ul
8
+ - @sections.each do |s|
9
+ %li{:class => ("active" if s == @section)}= menu_button_for(s)
10
+ #header
11
+ .title= @survey.title
12
+ .previous_section= previous_section
13
+ - unless @dependents.empty?
14
+ #dependents
15
+ .title Follow-up questions from your answers on the previous page
16
+ -# @dependents.each_with_index do |question, index|
17
+ = dependency_explanation_helper(question, @response_set)
18
+ = render(:partial => "/partials/question", :locals => {:question => question, :response_set => @response_set, :number => "D#{index+1}"})
19
+ - div_for @section do
20
+ %span.title= @section.title
21
+ .questions
22
+ - @section.questions.each_with_index do |question, index|
23
+ - unless question.part_of_group?
24
+ = render(:partial => "/partials/question", :locals => {:question => question, :response_set => @response_set})
25
+ - else # gather up the group questions
26
+ - (group_questions ||= []) << question
27
+ - if (index + 1 >= @section.questions.size) or (question.question_group_id != @section.questions[index + 1].question_group_id)
28
+ - # this is the last question of the section, or the group
29
+ = render(:partial => "/partials/question_group", :locals => {:question_group => question.question_group, :response_set => @response_set, :group_questions => group_questions})
30
+ - group_questions = []
31
+ .next_section= next_section
32
+
@@ -0,0 +1,17 @@
1
+ #surveyor
2
+ #header
3
+ .title= surveyor_config['default.title'] || "You can take these surveys:"
4
+ %br
5
+ #survey_list
6
+ %ul
7
+ - unless @surveys.empty?
8
+ - @surveys.each do |survey|
9
+ %li
10
+ - form_tag(take_survey_path(:survey_code => survey.access_code)) do
11
+ = hidden_field_tag("current_user_id", @current_user.nil? ? nil : @current_user.id)
12
+ = survey.title
13
+ &nbsp;
14
+ = submit_tag("Take it" )
15
+ - else
16
+ %li
17
+ No surveys
@@ -0,0 +1,12 @@
1
+ #surveyor
2
+ - @survey.sections.each do |section|
3
+ - div_for section do
4
+ .title= section.title
5
+ .questions
6
+ - @section.questions.each_with_index do |question, index|
7
+ - if question.part_of_group?
8
+ - if (index + 1 >= @section.questions.size) or (question.question_group_id != @section.questions[index + 1].question_group_id)
9
+ - # skip to the last question of the section, or the last question of the group
10
+ = render(:partial => "/partials/question_group", :locals => {:question_group => question.question_group, :response_set => @response_set})
11
+ - else
12
+ = render(:partial => "/partials/question", :locals => {:question => question, :response_set => @response_set})
@@ -0,0 +1,10 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ root = Surveyor::Config['default.relative_url_root'] || "surveys/"
3
+ map.with_options :controller => 'surveyor' do |s|
4
+ s.available_surveys "#{root}", :conditions => {:method => :get}, :action => "new" # GET survey list
5
+ s.take_survey "#{root}:survey_code", :conditions => {:method => :post}, :action => "create" # Only POST of survey to cre
6
+ s.view_my_survey "#{root}:survey_code/:response_set_code", :conditions => {:method => :get}, :action => "show" # GET viewable/printable? su
7
+ s.edit_my_survey "#{root}:survey_code/:response_set_code/take", :conditions => {:method => :get}, :action => "edit" # GET editable survey
8
+ s.update_my_survey "#{root}:survey_code/:response_set_code", :conditions => {:method => :put}, :action => "update" # PUT edited survey
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+
2
+ Any of surveyor's models class_eval, class methods, and instance methods can be modified. Include the following in config/initializers/surveyor.rb:
3
+
4
+ require 'models/survey_extensions' # Extended the survey model
5
+
6
+ SurveyorHelper class_eval and instance methods can be modified. Include the following in config/initializers/surveyor.rb:
7
+
8
+ require 'helpers/surveyor_helper_extensions' # Extend the surveyor helper
9
+
10
+ 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:
11
+
12
+ config['extend_controller'] = true
@@ -0,0 +1,22 @@
1
+ class SurveyorGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+
5
+ # Copy README to your app
6
+ m.file "EXTENDING_SURVEYOR", "surveyor/EXTENDING_SURVEYOR"
7
+
8
+ # Custom layout
9
+ m.file "extensions/surveyor_custom.html.erb", "app/views/layouts/surveyor_custom.html.erb"
10
+
11
+ # Model, helper, and controller extensions
12
+ # http://www.redmine.org/boards/3/topics/4095#message-4136
13
+ # http://blog.mattwynne.net/2009/07/11/rails-tip-use-polymorphism-to-extend-your-controllers-at-runtime/
14
+ m.file "extensions/survey_extensions.rb", "app/models/survey_extensions.rb"
15
+ m.file "extensions/surveyor_helper_extensions.rb", "app/helper/surveyor_helper_extensions.rb"
16
+ m.file "extensions/surveyor_controller_extensions.rb", "app/controllers/surveyor_controller_extensions.rb"
17
+
18
+ m.readme "EXTENDING_SURVEYOR"
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,60 @@
1
+ class SurveyorGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+
5
+ m.directory "surveys"
6
+
7
+ # Copy README to your app
8
+ m.file "../../../README.md", "surveys/README.md"
9
+
10
+ # Gem plugin rake tasks
11
+ m.file "tasks/surveyor.rb", "lib/tasks/surveyor.rb"
12
+ if file_has_line(destination_path('Rakefile'), /^require 'tasks\/surveyor'$/ )
13
+ logger.skipped 'Rakefile'
14
+ else
15
+ File.open(destination_path('Rakefile'), 'ab') {|file| file.write("\nrequire 'tasks/surveyor'\n") }
16
+ # http://ggr.com/how-to-include-a-gems-rake-tasks-in-your-rails-app.html
17
+ logger.appended 'Rakefile'
18
+ end
19
+
20
+ # HAML
21
+ m.file "initializers/surveyor.rb", "config/initializers/surveyor.rb"
22
+ m.file "initializers/haml.rb", "config/initializers/haml.rb"
23
+
24
+ # Migrate
25
+ # not using m.migration_template because all migration timestamps end up the same, causing a collision when running rake db:migrate
26
+ # coped functionality from RAILS_GEM_PATH/lib/rails_generator/commands.rb
27
+ m.directory "db/migrate"
28
+ ["surveys", "survey_sections", "questions", "answers", "response_sets", "responses", "dependencies", "question_groups", "dependency_conditions"].each_with_index do |model, i|
29
+ unless (prev_migrations = Dir.glob("db/migrate/[0-9]*_*.rb").grep(/[0-9]+_create_#{model}.rb$/)).empty?
30
+ prev_migration_timestamp = prev_migrations[0].match(/([0-9]+)_create_#{model}.rb$/)[1]
31
+ end
32
+ # raise "Another migration is already named create_#{model}" if not Dir.glob("db/migrate/[0-9]*_*.rb").grep(/[0-9]+_create_#{model}.rb$/).empty?
33
+ m.template("migrate/create_#{model}.rb", "db/migrate/#{(prev_migration_timestamp || Time.now.utc.strftime("%Y%m%d%H%M%S").to_i + i).to_s}_create_#{model}.rb")
34
+ end
35
+
36
+ # Generate CSS
37
+ css_root = File.join(File.dirname(__FILE__), "templates", "assets", "stylesheets")
38
+ `sass #{css_root}/sass/surveyor.sass #{css_root}/surveyor.css`
39
+
40
+ # Assets
41
+ ["images", "javascripts", "stylesheets"].each do |asset_type|
42
+ m.directory "public/#{asset_type}/surveyor"
43
+ Dir.glob(File.join(File.dirname(__FILE__), "templates", "assets", asset_type, "*.*")).map{|path| File.basename(path)}.each do |filename|
44
+ m.file "assets/#{asset_type}/#{filename}", "public/#{asset_type}/surveyor/#{filename}"
45
+ end
46
+ end
47
+
48
+ # Surveys
49
+ m.directory "surveys/fixtures"
50
+ m.file "surveys/kitchen_sink_survey.rb", "surveys/kitchen_sink_survey.rb"
51
+
52
+ m.readme "README"
53
+
54
+ end
55
+ end
56
+ def file_has_line(filename, rxp)
57
+ File.readlines(filename).each{ |line| return true if line =~ rxp }
58
+ false
59
+ end
60
+ end
@@ -0,0 +1,10 @@
1
+
2
+ Surveyor installed. Next, run the migrations:
3
+
4
+ rake db:migrate
5
+
6
+ Try out the "kitchen sink" survey:
7
+
8
+ rake surveyor FILE=surveys/kitchen_sink_survey.rb
9
+
10
+ Or see README.md for configuration and customization details