surveyor 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
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