surveyor 0.10.0 → 0.11.0
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.
- data/README.md +30 -11
- data/VERSION +1 -1
- data/app/controllers/surveyor_controller.rb +7 -0
- data/app/models/response_set.rb +22 -0
- data/app/models/survey.rb +1 -0
- data/app/views/partials/_answer.html.haml +13 -10
- data/app/views/surveyor/new.html.haml +0 -1
- data/config/routes.rb +5 -5
- data/generators/surveyor/surveyor_generator.rb +2 -1
- data/generators/surveyor/templates/migrate/add_index_to_response_sets.rb +9 -0
- data/generators/surveyor/templates/migrate/add_index_to_surveys.rb +9 -0
- data/generators/surveyor/templates/migrate/add_unique_indicies.rb +17 -0
- data/spec/factories.rb +3 -1
- data/spec/models/response_set_spec.rb +27 -0
- data/surveyor.gemspec +5 -2
- metadata +6 -3
data/README.md
CHANGED
@@ -106,15 +106,16 @@ The surveyor generator creates config/initializers/surveyor.rb. There, you can s
|
|
106
106
|
The initializer runs once, when the app starts. The block style is used to keep multiple options DRY (defaults below):
|
107
107
|
|
108
108
|
Surveyor::Config.run do |config|
|
109
|
-
config['default.relative_url_root'] = "surveys
|
110
|
-
config['default.title'] = "You can take these surveys:"
|
111
|
-
config['default.layout'] = "surveyor_default"
|
112
|
-
config['default.
|
113
|
-
config['
|
114
|
-
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['use_restful_authentication'] = false # set to true to use restful authentication
|
115
|
+
config['extend'] = %w() # %w(survey surveyor_helper surveyor_controller)
|
115
116
|
end
|
116
|
-
|
117
|
-
You can update surveyor's at any time. Use the block style (above), or the individual style:
|
117
|
+
|
118
|
+
You can update surveyor's configuration at any time. Use the block style (above), or the individual style:
|
118
119
|
|
119
120
|
Surveyor::Config['default.title'] = "Cheese is great!"
|
120
121
|
|
@@ -152,9 +153,7 @@ SurveyorController class_eval, class methods, instance methods, and actions can
|
|
152
153
|
</head>
|
153
154
|
<body>
|
154
155
|
<div id="flash"><%= flash[:notice] %></div>
|
155
|
-
|
156
|
-
<%= yield %>
|
157
|
-
</div>
|
156
|
+
<%= yield %>
|
158
157
|
</body>
|
159
158
|
</html>
|
160
159
|
|
@@ -175,6 +174,26 @@ To work on the plugin code (for enhancements, and bug fixes, etc...) fork this g
|
|
175
174
|
|
176
175
|
# Changes
|
177
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
|
+
|
178
197
|
0.9.11
|
179
198
|
|
180
199
|
* adding rails init.rb to make gem loading work. thanks mike gurley. closes #52.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.11.0
|
@@ -39,6 +39,13 @@ class SurveyorController < ApplicationController
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def show
|
42
|
+
@response_set = ResponseSet.find_by_access_code(params[:response_set_code], :include => {:responses => [:question, :answer]})
|
43
|
+
respond_to do |format|
|
44
|
+
format.html #{render :action => :show}
|
45
|
+
format.csv {
|
46
|
+
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")
|
47
|
+
}
|
48
|
+
end
|
42
49
|
end
|
43
50
|
|
44
51
|
def edit
|
data/app/models/response_set.rb
CHANGED
@@ -11,6 +11,7 @@ class ResponseSet < ActiveRecord::Base
|
|
11
11
|
# Validations
|
12
12
|
validates_presence_of :survey_id
|
13
13
|
validates_associated :responses
|
14
|
+
validates_uniqueness_of :access_code
|
14
15
|
|
15
16
|
# Attributes
|
16
17
|
attr_protected :completed_at
|
@@ -30,6 +31,27 @@ class ResponseSet < ActiveRecord::Base
|
|
30
31
|
self.access_code = Surveyor.make_tiny_code
|
31
32
|
end
|
32
33
|
|
34
|
+
def access_code=(val)
|
35
|
+
while ResponseSet.find_by_access_code(val)
|
36
|
+
val = Surveyor.make_tiny_code
|
37
|
+
end
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_csv
|
42
|
+
qcols = Question.content_columns.map(&:name) - %w(created_at updated_at)
|
43
|
+
acols = Answer.content_columns.map(&:name) - %w(created_at updated_at)
|
44
|
+
rcols = Response.content_columns.map(&:name)
|
45
|
+
require 'fastercsv'
|
46
|
+
FCSV(result = "") do |csv|
|
47
|
+
csv << qcols.map{|qcol| "question.#{qcol}"} + acols.map{|acol| "answer.#{acol}"} + rcols.map{|rcol| "response.#{rcol}"}
|
48
|
+
responses.each do |response|
|
49
|
+
csv << qcols.map{|qcol| response.question.send(qcol)} + acols.map{|acol| response.answer.send(acol)} + rcols.map{|rcol| response.send(rcol)}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
result
|
53
|
+
end
|
54
|
+
|
33
55
|
def response_for(question_id, answer_id, group = nil)
|
34
56
|
found = responses.detect{|r| r.question_id == question_id && r.answer_id == answer_id && r.response_group.to_s == group.to_s}
|
35
57
|
found.blank? ? responses.new(:question_id => question_id, :answer_id => answer_id, :response_group => group) : found
|
data/app/models/survey.rb
CHANGED
@@ -16,20 +16,23 @@
|
|
16
16
|
= response_form.survey_check_box(:selected, :class => (answer.is_exclusive? ? "exclusive" : ""))
|
17
17
|
= response_form.label(:answer_id, answer.text)
|
18
18
|
= response_form.text_field(:string_value, :size => 25, :maxlength => 250)
|
19
|
-
- when :one_answer, :one_string
|
19
|
+
- when :one_answer, :one_string, :one_integer
|
20
20
|
- fields_for_radio(response_obj) do |radio_form|
|
21
21
|
= radio_form.radio_button(:answer_id, answer.id, :checked => response_obj.selected?, :title => answer.text)
|
22
|
-
= radio_form.label("answer_id_#{answer.id}", answer.text
|
23
|
-
|
24
|
-
|
22
|
+
= radio_form.label("answer_id_#{answer.id}", split_text(answer.text)[:prefix]) unless hide_label
|
23
|
+
- if renderer == :one_string
|
24
|
+
= response_form.text_field(:string_value, :size => 25, :maxlength => 250, :autocomplete => "off")
|
25
|
+
- if renderer == :one_integer
|
26
|
+
= response_form.text_field(:integer_value, :size => 5, :maxlength => 10, :autocomplete => "off")
|
27
|
+
= radio_form.label("answer_id_#{answer.id}", split_text(answer.text)[:postfix]) unless hide_label
|
25
28
|
- when :none_date
|
26
|
-
= response_form.label(:
|
29
|
+
= response_form.label(:datetime_value, split_text(answer.text)[:prefix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
|
27
30
|
= response_form.text_field(:datetime_value)
|
28
|
-
= response_form.label(:
|
31
|
+
= response_form.label(:datetime_value, split_text(answer.text)[:postfix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
|
29
32
|
- when :none_datetime
|
30
|
-
= response_form.label(:
|
33
|
+
= response_form.label(:datetime_value, split_text(answer.text)[:prefix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
|
31
34
|
= response_form.datetime_select(:datetime_value, {:include_blank => true})
|
32
|
-
= response_form.label(:
|
35
|
+
= response_form.label(:datetime_value, split_text(answer.text)[:postfix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
|
33
36
|
- when :none_float
|
34
37
|
= response_form.label(:float_value, split_text(answer.text)[:prefix]) unless hide_label
|
35
38
|
= response_form.text_field(:float_value, :size => 5, :maxlength => 10, :autocomplete => "off")
|
@@ -47,9 +50,9 @@
|
|
47
50
|
= response_form.text_area(:text_value, :cols => 80, :rows => 10)
|
48
51
|
= response_form.label(:text_value, split_text(answer.text)[:postfix]) unless hide_label
|
49
52
|
- when :none_time
|
50
|
-
= response_form.label(:
|
53
|
+
= response_form.label(:datetime_value, split_text(answer.text)[:prefix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
|
51
54
|
= response_form.time_select(:datetime_value,{ :include_blank => true })
|
52
|
-
= response_form.label(:
|
55
|
+
= response_form.label(:datetime_value, split_text(answer.text)[:postfix], :class => "#{(disabled)? 'disabled' : 'enabled'}") unless hide_label
|
53
56
|
- else
|
54
57
|
= answer.text
|
55
58
|
|
data/config/routes.rb
CHANGED
@@ -2,10 +2,10 @@ ActionController::Routing::Routes.draw do |map|
|
|
2
2
|
root = Surveyor::Config['default.relative_url_root'] || "surveys"
|
3
3
|
root = (root << "/").gsub(/\/+/, "/")
|
4
4
|
map.with_options :controller => 'surveyor' do |s|
|
5
|
-
s.available_surveys "#{root}",
|
6
|
-
s.take_survey "#{root}:survey_code",
|
7
|
-
s.view_my_survey "#{root}:survey_code/:response_set_code",
|
8
|
-
s.edit_my_survey "#{root}:survey_code/:response_set_code/take",
|
9
|
-
s.update_my_survey "#{root}:survey_code/:response_set_code",
|
5
|
+
s.available_surveys "#{root}", :conditions => {:method => :get}, :action => "new" # GET survey list
|
6
|
+
s.take_survey "#{root}:survey_code", :conditions => {:method => :post}, :action => "create" # Only POST of survey to create
|
7
|
+
s.view_my_survey "#{root}:survey_code/:response_set_code.:format", :conditions => {:method => :get}, :action => "show", :format => "html" # GET viewable/printable? survey
|
8
|
+
s.edit_my_survey "#{root}:survey_code/:response_set_code/take", :conditions => {:method => :get}, :action => "edit" # GET editable survey
|
9
|
+
s.update_my_survey "#{root}:survey_code/:response_set_code", :conditions => {:method => :put}, :action => "update" # PUT edited survey
|
10
10
|
end
|
11
11
|
end
|
@@ -29,7 +29,8 @@ class SurveyorGenerator < Rails::Generator::Base
|
|
29
29
|
"create_response_sets", "create_responses",
|
30
30
|
"create_dependencies", "create_dependency_conditions",
|
31
31
|
"create_validations", "create_validation_conditions",
|
32
|
-
"add_display_order_to_surveys", "add_correct_answer_id_to_questions"
|
32
|
+
"add_display_order_to_surveys", "add_correct_answer_id_to_questions",
|
33
|
+
"add_index_to_response_sets", "add_index_to_surveys", "add_unique_indicies"].each_with_index do |model, i|
|
33
34
|
unless (prev_migrations = Dir.glob("db/migrate/[0-9]*_*.rb").grep(/[0-9]+_#{model}.rb$/)).empty?
|
34
35
|
prev_migration_timestamp = prev_migrations[0].match(/([0-9]+)_#{model}.rb$/)[1]
|
35
36
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class AddUniqueIndicies < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
remove_index(:response_sets, :name => 'response_sets_ac_idx')
|
4
|
+
add_index(:response_sets, :access_code, :name => 'response_sets_ac_idx', :unique => true)
|
5
|
+
|
6
|
+
remove_index(:surveys, :name => 'surveys_ac_idx')
|
7
|
+
add_index(:surveys, :access_code, :name => 'surveys_ac_idx', :unique => true)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
remove_index(:response_sets, :name => 'response_sets_ac_idx')
|
12
|
+
add_index(:response_sets, :access_code, :name => 'response_sets_ac_idx')
|
13
|
+
|
14
|
+
remove_index(:surveys, :name => 'surveys_ac_idx')
|
15
|
+
add_index(:surveys, :access_code, :name => 'surveys_ac_idx')
|
16
|
+
end
|
17
|
+
end
|
data/spec/factories.rb
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'factory_girl'
|
4
4
|
|
5
|
+
Factory.sequence(:unique_survey_access_code){|n| "simple_survey" << n.to_s }
|
6
|
+
|
5
7
|
Factory.define :survey do |s|
|
6
8
|
s.title {"Simple survey"}
|
7
9
|
s.description {"A simple survey for testing"}
|
8
|
-
s.access_code {
|
10
|
+
s.access_code {Factory.next :unique_survey_access_code}
|
9
11
|
s.active_at {Time.now}
|
10
12
|
s.inactive_at {}
|
11
13
|
s.css_url {}
|
@@ -215,4 +215,31 @@ describe ResponseSet, "with mandatory, dependent questions" do
|
|
215
215
|
@response_set.mandatory_questions_complete?.should be_true
|
216
216
|
@response_set.progress_hash.should == {:questions => 4, :triggered => 4, :triggered_mandatory => 4, :triggered_mandatory_completed => 4}
|
217
217
|
end
|
218
|
+
end
|
219
|
+
describe ResponseSet, "exporting csv" do
|
220
|
+
before(:each) do
|
221
|
+
@section = Factory(:survey_section)
|
222
|
+
# Questions
|
223
|
+
@do_you_like_pie = Factory(:question, :text => "Do you like pie?", :survey_section => @section)
|
224
|
+
@what_flavor = Factory(:question, :text => "What flavor?", :survey_section => @section)
|
225
|
+
@what_bakery = Factory(:question, :text => "What bakery?", :survey_section => @section)
|
226
|
+
# Answers
|
227
|
+
@do_you_like_pie.answers << Factory(:answer, :text => "yes", :question_id => @do_you_like_pie.id)
|
228
|
+
@do_you_like_pie.answers << Factory(:answer, :text => "no", :question_id => @do_you_like_pie.id)
|
229
|
+
@what_flavor.answers << Factory(:answer, :response_class => :string, :question_id => @what_flavor.id)
|
230
|
+
@what_bakery.answers << Factory(:answer, :response_class => :string, :question_id => @what_bakery.id)
|
231
|
+
# Responses
|
232
|
+
@response_set = Factory(:response_set)
|
233
|
+
@response_set.current_section_id = @section.id
|
234
|
+
@response_set.responses << Factory(:response, :question_id => @do_you_like_pie.id, :answer_id => @do_you_like_pie.answers.first.id, :response_set_id => @response_set.id)
|
235
|
+
@response_set.responses << Factory(:response, :string_value => "pecan pie", :question_id => @what_flavor.id, :answer_id => @what_flavor.answers.first.id, :response_set_id => @response_set.id)
|
236
|
+
end
|
237
|
+
it "should export a string with responses" do
|
238
|
+
@response_set.responses.size.should == 2
|
239
|
+
csv = @response_set.to_csv
|
240
|
+
csv.is_a?(String).should be_true
|
241
|
+
csv.should match "question.short_text"
|
242
|
+
csv.should match "What flavor?"
|
243
|
+
csv.should match /pecan pie/
|
244
|
+
end
|
218
245
|
end
|
data/surveyor.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{surveyor}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.11.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Chamberlain", "Mark Yoon"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-06}
|
13
13
|
s.email = %q{yoon@northwestern.edu}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.md"
|
@@ -111,6 +111,9 @@ Gem::Specification.new do |s|
|
|
111
111
|
"generators/surveyor/templates/initializers/surveyor.rb",
|
112
112
|
"generators/surveyor/templates/migrate/add_correct_answer_id_to_questions.rb",
|
113
113
|
"generators/surveyor/templates/migrate/add_display_order_to_surveys.rb",
|
114
|
+
"generators/surveyor/templates/migrate/add_index_to_response_sets.rb",
|
115
|
+
"generators/surveyor/templates/migrate/add_index_to_surveys.rb",
|
116
|
+
"generators/surveyor/templates/migrate/add_unique_indicies.rb",
|
114
117
|
"generators/surveyor/templates/migrate/create_answers.rb",
|
115
118
|
"generators/surveyor/templates/migrate/create_dependencies.rb",
|
116
119
|
"generators/surveyor/templates/migrate/create_dependency_conditions.rb",
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 11
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.11.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brian Chamberlain
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-04-
|
18
|
+
date: 2010-04-06 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -135,6 +135,9 @@ files:
|
|
135
135
|
- generators/surveyor/templates/initializers/surveyor.rb
|
136
136
|
- generators/surveyor/templates/migrate/add_correct_answer_id_to_questions.rb
|
137
137
|
- generators/surveyor/templates/migrate/add_display_order_to_surveys.rb
|
138
|
+
- generators/surveyor/templates/migrate/add_index_to_response_sets.rb
|
139
|
+
- generators/surveyor/templates/migrate/add_index_to_surveys.rb
|
140
|
+
- generators/surveyor/templates/migrate/add_unique_indicies.rb
|
138
141
|
- generators/surveyor/templates/migrate/create_answers.rb
|
139
142
|
- generators/surveyor/templates/migrate/create_dependencies.rb
|
140
143
|
- generators/surveyor/templates/migrate/create_dependency_conditions.rb
|