surveyor 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/README.md +22 -5
  2. data/VERSION +1 -1
  3. data/app/models/dependency.rb +16 -32
  4. data/app/models/question.rb +1 -1
  5. data/app/models/question_group.rb +1 -1
  6. data/app/models/response.rb +1 -4
  7. data/app/models/response_set.rb +4 -3
  8. data/app/models/survey.rb +0 -1
  9. data/app/models/validation.rb +20 -0
  10. data/app/models/validation_condition.rb +19 -17
  11. data/generators/surveyor/surveyor_generator.rb +9 -5
  12. data/generators/surveyor/templates/migrate/add_display_order_to_surveys.rb +9 -0
  13. data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +15 -4
  14. data/lib/surveyor.rb +16 -0
  15. data/script/surveyor/answer.rb +32 -55
  16. data/script/surveyor/base.rb +61 -0
  17. data/script/surveyor/dependency.rb +4 -41
  18. data/script/surveyor/dependency_condition.rb +13 -38
  19. data/script/surveyor/question.rb +16 -50
  20. data/script/surveyor/question_group.rb +7 -19
  21. data/script/surveyor/specs/answer_spec.rb +15 -52
  22. data/script/surveyor/specs/question_spec.rb +37 -85
  23. data/script/surveyor/specs/spec_helper.rb +6 -0
  24. data/script/surveyor/specs/survey_section_spec.rb +23 -0
  25. data/script/surveyor/specs/validation_condition_spec.rb +20 -0
  26. data/script/surveyor/specs/validation_spec.rb +20 -0
  27. data/script/surveyor/survey.rb +10 -85
  28. data/script/surveyor/survey_parser.rb +160 -38
  29. data/script/surveyor/survey_section.rb +6 -130
  30. data/script/surveyor/validation.rb +19 -0
  31. data/script/surveyor/validation_condition.rb +19 -0
  32. data/spec/lib/surveyor_spec.rb +44 -0
  33. data/spec/models/dependency_spec.rb +9 -16
  34. data/spec/models/question_group_spec.rb +3 -3
  35. data/spec/models/question_spec.rb +1 -1
  36. data/spec/models/validation_condition_spec.rb +29 -0
  37. data/spec/models/validation_spec.rb +27 -0
  38. data/spec/spec_helper.rb +0 -2
  39. data/surveyor.gemspec +12 -7
  40. metadata +12 -7
  41. data/lib/tiny_code.rb +0 -58
  42. data/script/surveyor/columnizer.rb +0 -36
  43. data/script/surveyor/specs/question_dependency_spec.rb +0 -46
  44. data/script/surveyor/specs/question_group_spec.rb +0 -9
  45. data/script/surveyor/specs/section_spec.rb +0 -58
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
2
+ require File.expand_path(File.dirname(__FILE__) + "/../../../lib/surveyor")
3
+ require File.expand_path(File.dirname(__FILE__) + "/../base")
4
+
5
+ Spec::Runner.configure do |config|
6
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'survey_section'
3
+
4
+ describe SurveySection, "when first created" do
5
+
6
+ before(:each) do
7
+ @section = SurveySection.new(mock("Survey", :id => 2, :parser => mock("Parser", :new_survey_section_id => 1)), ["Demographics"], {})
8
+ end
9
+
10
+ it "should generate a data export identifier" do
11
+ @section.data_export_identifier.should == "demographics"
12
+ end
13
+
14
+ it "should find a question by reference" do
15
+ @section.questions << mock("Question", :reference_identifier => "1", :text => "foo")
16
+ @section.questions << mock("Question", :reference_identifier => "2", :text => "foo")
17
+ @section.questions << mock("Question", :reference_identifier => "3", :text => "foo")
18
+
19
+ q = @section.find_question_by_reference("2")
20
+ q.should_not be_nil
21
+ q.reference_identifier.should == "2"
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'validation_condition'
3
+
4
+ describe ValidationCondition, " when first created" do
5
+ before do
6
+ validation = mock("Validation", :id => 29, :parser => mock("Parser", :new_validation_condition_id => 21))
7
+ validation.stub!(:class => Validation)
8
+ args = [">=", {:integer_value => 0}]
9
+ options = {}
10
+ @validation_condition = ValidationCondition.new(validation, args, options)
11
+ end
12
+
13
+ it "should set initialization parameters properly" do
14
+ @validation_condition.id.should == 21
15
+ @validation_condition.validation_id.should == 29
16
+ @validation_condition.integer_value.should == 0
17
+ @validation_condition.operator.should == ">="
18
+ end
19
+
20
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'validation'
3
+
4
+ describe Validation, " when first created" do
5
+ before do
6
+ answer = mock("Answer", :id => 2, :parser => mock("Parser", :new_validation_id => 1))
7
+ answer.stub!(:class => Answer)
8
+ args = [{:rule => "C", :message => "Please select a number between 0 and 120"}]
9
+ options = {}
10
+ @validation = Validation.new(answer, args, options)
11
+ end
12
+
13
+ it "should set initialization parameters properly" do
14
+ @validation.id.should == 1
15
+ @validation.message.should == "Please select a number between 0 and 120"
16
+ @validation.answer_id.should == 2
17
+ @validation.rule.should == "C"
18
+ end
19
+
20
+ end
@@ -1,85 +1,25 @@
1
- require File.dirname(__FILE__) + '/survey_section'
2
-
3
- class Survey
4
- include Columnizer
5
- # Context, Content, Reference, Expiry, Display, Children
1
+ class Survey < SurveyParser::Base
2
+ # Context, Content, Reference, Expiry, Display
6
3
  attr_accessor :id, :parser
7
4
  attr_accessor :title, :description
8
5
  attr_accessor :access_code, :reference_identifier, :data_export_identifier, :common_namespace, :common_identitier
9
6
  attr_accessor :active_at, :inactive_at
10
7
  attr_accessor :css_url, :custom_class
11
- attr_accessor :survey_sections
12
-
13
- @@current_survey = nil
14
-
15
- def self.current_survey
16
- @@current_survey
17
- end
18
-
19
- def self.current_survey=(value)
20
- @@current_survey = value
21
- puts "Assigning current survey #{@@current_survey.title}"
22
- end
8
+ has_children :survey_sections
23
9
 
24
- # id, parser, and title required
25
- def initialize(id, parser, title, options = {})
26
- self.id = id
27
- self.parser = parser
28
- self.title = title
29
- self.survey_sections = []
30
- self.access_code = Columnizer.to_normalized_column(title)
31
- # self.default_options(title).merge(options).each{|key,value| self.instance_variable_set("@#{key}", value)}
32
- Survey.current_survey = self
10
+ def parse_args(args)
11
+ title = args[0]
12
+ {:title => title, :access_code => Surveyor.to_normalized_string(title)}.merge(args[1] || {})
33
13
  end
34
-
35
- # def default_options(title)
36
- # {}
37
- # end
38
14
 
39
- # This method_missing magic does all the heavy lifting for the DSL
40
- def method_missing(missing_method, *args, &block)
41
- m_name = missing_method.to_s
42
- if (section_match = m_name.match(/(\Asection)_?(.*)/))
43
- build_survey_section(section_match[3].to_s, *args, &block) # Parse "section" method, create new section in this survey
44
- else
45
- puts " ERROR: '#{m_name}' not valid method_missing name"
46
- end
47
- end
48
-
49
- def build_survey_section(reference_identifier, title, &block)
50
- puts " Section: #{title}"
51
- if block_given?
52
- new_survey_section = SurveySection.new(new_survey_section_id, self, title, {:display_order => self.survey_sections.size + 1, :reference_identifier => reference_identifier})
53
- new_survey_section.instance_eval(&block)
54
- add_survey_section(new_survey_section)
55
- puts " Section added"
56
- else
57
- puts " ERROR: A section cannot be empty!"
58
- end
59
- end
60
-
61
- def new_survey_section_id
62
- self.parser.new_survey_section_id
63
- end
64
-
65
- def add_survey_section(survey_section)
66
- self.survey_sections << survey_section
67
- end
68
-
69
- # Used to find questions for dependency linking
70
15
  def find_question_by_reference(ref_id)
71
- question = nil
72
- count = 0
73
- while question.nil? and count < self.survey_sections.size
74
- question = self.survey_sections[count].find_question_by_reference(ref_id)
75
- count += 1
76
- end
77
- question
16
+ found = nil
17
+ survey_sections.detect{|s| found = s.find_question_by_reference(ref_id)}
18
+ return found
78
19
  end
79
20
 
80
-
81
21
  def reconcile_dependencies
82
- @survey_sections.each do |section|
22
+ survey_sections.each do |section|
83
23
  section.questions.each do |question|
84
24
  question.dependency.dependency_conditions.each { |con| con.reconcile_dependencies} unless question.dependency.nil?
85
25
  end
@@ -89,19 +29,4 @@ class Survey
89
29
  end
90
30
  end
91
31
 
92
- def yml_attrs
93
- instance_variables.sort - ["@parser", "@survey_sections"]
94
- end
95
- def to_yml
96
- out = [ %(survey_#{@id}:) ]
97
- yml_attrs.each{|a| out << " #{a[1..-1]}: #{instance_variable_get(a).is_a?(String) ? "\"#{instance_variable_get(a)}\"" : instance_variable_get(a) }"}
98
- (out << nil ).join("\r\n")
99
- end
100
-
101
- def to_file
102
- "survey -#{self.title}- written to file..."
103
- File.open(self.parser.surveys_yml, File::CREAT|File::APPEND|File::WRONLY) {|f| f << to_yml}
104
- self.survey_sections.compact.map(&:to_file)
105
- end
106
-
107
32
  end
@@ -1,60 +1,182 @@
1
- require File.dirname(__FILE__) + '/survey'
1
+ require 'activesupport' # for pluralize, humanize in ActiveSupport::CoreExtensions::String::Inflections
2
2
 
3
3
  class SurveyParser
4
- # Children, Counters, Files
5
- attr_accessor :surveys
6
- attr_accessor :last_survey_id, :last_survey_section_id, :last_question_id, :last_answer_id
7
- attr_accessor :surveys_yml, :survey_sections_yml, :question_groups_yml, :questions_yml, :answers_yml, :dependencies_yml, :dependency_conditions_yml
4
+ @@models = %w(survey survey_section question_group question answer dependency dependency_condition validation validation_condition)
5
+
6
+ # Require base and all models
7
+ (%w(base) + @@models).each{|m| require File.dirname(__FILE__) + "/#{m}"}
8
8
 
9
- # no more "ARRRGH, EVIL GLOBALS!!!"
10
- def initialize
11
- self.surveys = []
12
- self.define_counter_methods(%w(survey survey_section question_group question answer dependency dependency_condition))
13
- self.initialize_fixtures(%w(surveys survey_sections question_groups questions answers dependencies dependency_conditions), File.join(RAILS_ROOT, "surveys", "fixtures"))
9
+ # Attributes
10
+ attr_accessor :surveys, :grid_answers
11
+ @@models.each{|m| attr_accessor "#{m.pluralize}_yml".to_sym } # for fixtures
12
+ (@@models - %w(dependency_condition validation_condition)).each {|m| attr_accessor "current_#{m}".to_sym} # for current_model caches
13
+
14
+ # Class methods
15
+ def self.parse(file_name)
16
+ self.define_counter_methods(@@models)
17
+ puts "\n--- Parsing '#{file_name}' ---"
18
+ parser = SurveyParser.new
19
+ parser.instance_eval(File.read(file_name))
20
+ parser.to_files
21
+ puts "--- End of parsing ---\n\n"
14
22
  end
15
23
 
16
24
  # new_survey_id, new_survey_section_id, etc.
17
- def define_counter_methods(names)
25
+ def self.define_counter_methods(names)
18
26
  names.each do |name|
19
- self.instance_variable_set("@last_#{name}_id", 0)
20
- # self.class.send is a hack - define_method is private
21
- self.class.send(:define_method, "new_#{name}_id") do
22
- self.instance_variable_set("@last_#{name}_id", self.instance_variable_get("@last_#{name}_id") + 1)
27
+ define_method("new_#{name}_id") do
28
+ instance_variable_set("@last_#{name}_id", instance_variable_get("@last_#{name}_id") + 1)
23
29
  end
24
30
  end
25
31
  end
32
+
33
+ # Instance methods
34
+ def initialize
35
+ self.surveys = []
36
+ self.grid_answers = []
37
+ initialize_counters(@@models)
38
+ initialize_fixtures(@@models.map(&:pluralize), File.join(RAILS_ROOT, "surveys", "fixtures"))
39
+ end
40
+
41
+ # @last_survey_id, @last_survey_section_id, etc.
42
+ def initialize_counters(names)
43
+ names.each{|name| instance_variable_set("@last_#{name}_id", 0)}
44
+ end
26
45
 
27
- # surveys_yml, survey_sections_yml, etc.
46
+ # @surveys_yml, @survey_sections_yml, etc.
28
47
  def initialize_fixtures(names, path)
29
- names.each do |name|
30
- file = self.instance_variable_set("@#{name}_yml", "#{path}/#{name}.yml")
31
- File.truncate(file, 0) if File.exist?(file)
32
- end
48
+ names.each {|name| file = instance_variable_set("@#{name}_yml", "#{path}/#{name}.yml"); File.truncate(file, 0) if File.exist?(file) }
33
49
  end
34
50
 
35
- def self.parse(file_name)
36
- puts "--- Parsing '#{file_name}' ---"
37
- parser = SurveyParser.new
38
- parser.instance_eval(File.read(file_name), file_name)
39
- parser.to_files
40
- puts "--- End of parsing ---"
41
- end
51
+ # This method_missing does all the heavy lifting for the DSL
52
+ def method_missing(missing_method, *args, &block)
53
+ method_name, reference_identifier = missing_method.to_s.split("_", 2)
54
+ opts = {:method_name => method_name, :reference_identifier => reference_identifier}
55
+ case method_name
56
+ when "survey"
57
+ self.current_survey = Survey.new(self, args, opts)
58
+ evaluate_the "survey", &block
59
+
60
+ when "section"
61
+ self.current_survey_section = SurveySection.new(self.current_survey, args, opts.merge({:display_order => current_survey.survey_sections.size + 1}))
62
+ evaluate_the "survey_section", &block
63
+
64
+ when "group", "g", "grid", "repeater"
65
+ self.current_question_group = QuestionGroup.new(self.current_survey_section, args, opts)
66
+ evaluate_the "question_group", &block
67
+
68
+ when "question", "q", "label", "image"
69
+ drop_the &block
70
+ self.current_question = Question.new(self.current_survey_section, args, opts.merge(:question_group_id => current_question_group ? current_question_group.id : nil))
71
+ add_grid_answers if in_a_grid?
72
+
73
+ when "dependency", "d"
74
+ drop_the &block
75
+ self.current_dependency = Dependency.new(self.current_question_group || current_question, args, opts)
76
+
77
+ when "condition", "c"
78
+ drop_the &block
79
+ raise "Error: No current dependency or validation for this condition" if self.current_dependency.nil? && self.current_validation.nil?
80
+ if self.current_dependency.nil?
81
+ self.current_validation.validation_conditions << ValidationCondition.new(self.current_validation, args, opts)
82
+ else
83
+ self.current_dependency.dependency_conditions << DependencyCondition.new(self.current_dependency, args, opts)
84
+ end
85
+
86
+ when "answer", "a"
87
+ drop_the &block
88
+ if in_a_grid?
89
+ self.grid_answers << Answer.new(nil, args, opts.merge(:display_order => grid_answers.size + 1))
90
+ else
91
+ raise "Error: No current question" if self.current_question.nil?
92
+ self.current_answer = Answer.new(self.current_question, args, opts.merge(:display_order => current_question.answers.size + 1))
93
+ end
94
+
95
+ when "validation", "v"
96
+ drop_the &block
97
+ self.current_validation = Validation.new(self.current_answer, args, opts)
42
98
 
43
- def survey(title, &block)
44
- puts "Survey: #{title}"
45
- if block_given?
46
- new_survey = Survey.new(self.new_survey_id, self, title)
47
- new_survey.instance_eval(&block)
48
- new_survey.reconcile_dependencies
49
- add_survey(new_survey)
50
- puts "Survey added"
51
99
  else
52
- puts "ERROR: A survey cannot be empty!"
100
+ raise " ERROR: '#{method_name}' not valid method"
101
+
102
+ end
103
+ end
104
+
105
+ def drop_the(&block)
106
+ raise "Error, I'm dropping the block like it's hot" if block_given?
107
+ end
108
+
109
+ def evaluate_the(model, &block)
110
+ raise "Error: A #{model.humanize} cannot be empty" unless block_given?
111
+ self.instance_eval(&block)
112
+ self.send("clear_current", model)
113
+ end
114
+
115
+ def clear_current(model)
116
+ # puts "clear_current #{model}"
117
+ case model
118
+ when "survey"
119
+ self.current_survey.reconcile_dependencies unless current_survey.nil?
120
+ when "question_group"
121
+ self.grid_answers = []
122
+ clear_current("question")
123
+ when "question"
124
+ @current_dependency = nil
125
+ when "answer"
126
+ @current_validation = nil
53
127
  end
128
+ instance_variable_set("@current_#{model}", nil)
129
+ model.classify.constantize.send(:children).each{|m| clear_current(m.to_s.singularize)}
130
+ end
131
+
132
+ def current_survey=(s)
133
+ clear_current "survey"
134
+ self.surveys << s
135
+ @current_survey = s
136
+ end
137
+ def current_survey_section=(s)
138
+ clear_current "survey_section"
139
+ self.current_survey.survey_sections << s
140
+ @current_survey_section = s
141
+ end
142
+ def current_question_group=(g)
143
+ clear_current "question_group"
144
+ self.current_survey_section.question_groups << g
145
+ @current_question_group = g
146
+ end
147
+ def current_question=(q)
148
+ clear_current "question"
149
+ self.current_survey_section.questions << q
150
+ @current_question = q
151
+ end
152
+ def current_dependency=(d)
153
+ raise "Error: No question or question group" unless (dependent = self.current_question_group || self.current_question)
154
+ dependent.dependency = d
155
+ @current_dependency = d
156
+ end
157
+ def current_answer=(a)
158
+ raise "Error: No current question" if self.current_question.nil?
159
+ self.current_question.answers << a
160
+ @current_answer = a
161
+ end
162
+ def current_validation=(v)
163
+ clear_current "validation"
164
+ self.current_answer.validation = v
165
+ @current_validation = v
54
166
  end
55
167
 
56
- def add_survey(survey)
57
- self.surveys << survey
168
+ def in_a_grid?
169
+ self.current_question_group and self.current_question_group.display_type == "grid"
170
+ end
171
+
172
+ def add_grid_answers
173
+ self.grid_answers.each do |grid_answer|
174
+ my_answer = grid_answer.dup
175
+ my_answer.id = new_answer_id
176
+ my_answer.question_id = self.current_question.id
177
+ my_answer.parser = self
178
+ self.current_answer = my_answer
179
+ end
58
180
  end
59
181
 
60
182
  def to_files
@@ -1,143 +1,19 @@
1
- require File.dirname(__FILE__) + '/question_group'
2
- require File.dirname(__FILE__) + '/question'
3
- require File.dirname(__FILE__) + '/answer'
4
- require File.dirname(__FILE__) + '/dependency'
5
- require File.dirname(__FILE__) + '/dependency_condition'
6
- require File.dirname(__FILE__) + '/columnizer'
7
- require 'activesupport'
8
- #require 'activesupport/lib/active_support/core_ext/string/inflections'
9
-
10
- class SurveySection
11
- include Columnizer
12
-
1
+ class SurveySection < SurveyParser::Base
13
2
  # Context, Content, Display, Reference, Children, Placeholders
14
3
  attr_accessor :id, :parser, :survey_id
15
4
  attr_accessor :title, :description
16
5
  attr_accessor :reference_identifier, :data_export_identifier, :common_namespace, :common_identitier
17
6
  attr_accessor :display_order, :custom_class
18
- attr_accessor :question_groups, :questions, :grid_answers
19
- attr_accessor :current_question_group, :current_question, :current_dependency
7
+ has_children :question_groups, :questions
20
8
 
21
- # id, survey, and title required
22
- def initialize(id, survey, title, options = {})
23
- self.id = id
24
- self.survey_id = survey.id
25
- self.parser = survey.parser
26
- self.title = title.strip
27
- self.questions = []
28
- self.question_groups = []
29
- self.grid_answers = []
30
- self.current_question_group = nil
31
- self.current_question = nil
32
- self.current_dependency = nil
33
- self.default_options(title).merge(options).each{|key,value| self.instance_variable_set("@#{key}", value)}
9
+ def parse_args(args)
10
+ title = args[0]
11
+ {:title => title, :data_export_identifier => Surveyor.to_normalized_string(title)}.merge(args[1] || {})
34
12
  end
35
13
 
36
- def default_options(title)
37
- { :data_export_identifier => Columnizer.to_normalized_column(title)
38
- }
39
- end
40
-
41
- # This method_missing magic does all the heavy lifting for the DSL
42
- def method_missing(missing_method, *args, &block)
43
- method_name, reference_identifier = missing_method.to_s.split("_")
44
-
45
- case method_name
46
-
47
- when "group", "g", "grid", "repeater"
48
- puts " Group: #{reference_identifier}"
49
- raise "Error: A question group cannot be empty" unless block_given?
50
-
51
- clear_current_question
52
- options = {:reference_identifier => reference_identifier, :display_type => (method_name =~ /grid|repeater/)? method_name : nil }
53
- self.question_groups << (self.current_question_group = QuestionGroup.new(self, args, options))
54
- self.instance_eval(&block)
55
- clear_current_question_group
56
-
57
- when "question", "q", "label", "image"
58
- puts " Question: #{reference_identifier}"
59
- raise "Error: I'm dropping the block like it's hot" if block_given?
60
-
61
- clear_current_question
62
- options = {:reference_identifier => reference_identifier, :question_group_id => (current_question_group ? current_question_group.id : nil)}
63
- options.merge!({:display_type => "label"}) if method_name == "label"
64
- options.merge!({:display_type => "image"}) if method_name == "image"
65
- self.questions << (self.current_question = Question.new(self, args, options))
66
- add_grid_answers if self.current_question_group and self.current_question_group.display_type == "grid"
67
-
68
- when "dependency", "d"
69
- puts " Dependency: #{reference_identifier}"
70
- raise "Error: I'm dropping the block like it's hot" if block_given?
71
- raise "Error: No question or question group" unless (d = self.current_question_group || self.current_question)
72
-
73
- options = {}# {:reference_identifier => reference_identifier}
74
- d.dependency = (self.current_dependency = Dependency.new(d, args, options))
75
-
76
- when "condition", "c"
77
- puts " Condition: #{reference_identifier}"
78
- raise "Error, I'm dropping the block like it's hot" if block_given?
79
- raise "Error: No current dependency" unless self.current_dependency
80
-
81
- options = {:rule_key => reference_identifier}
82
- self.current_dependency.add_dependency_condition DependencyCondition.new(self, args, options)
83
-
84
- when "answer", "a"
85
- puts " Answer: #{reference_identifier}"
86
- raise "Error, I'm dropping the block like it's hot" if block_given?
87
-
88
- if self.current_question_group and self.current_question_group.display_type == "grid"
89
- options = {:reference_identifier => reference_identifier, :display_order => self.grid_answers.size + 1}
90
- self.grid_answers << Answer.new(nil, args, options)
91
- else
92
- raise "Error: No current question" unless self.current_question
93
- options = {:reference_identifier => reference_identifier, :display_order => self.current_question.answers.size + 1}
94
- self.current_question.answers << Answer.new(self.current_question, args, options)
95
- end
96
-
97
- else
98
- raise " ERROR: '#{m_name}' not valid method_missing name"
99
- end
100
- end
101
-
102
- def clear_current_question_group
103
- self.current_question_group = nil
104
- self.grid_answers = []
105
- self.current_question = nil
106
- end
107
-
108
- def clear_current_question
109
- self.current_question = nil
110
- self.current_dependency = nil
111
- end
112
-
113
- def add_grid_answers
114
- self.grid_answers.each do |grid_answer|
115
- my_answer = grid_answer.dup
116
- my_answer.id = self.parser.new_answer_id
117
- my_answer.question_id = self.current_question.id
118
- my_answer.parser = self.parser
119
- self.current_question.answers << my_answer
120
- end
121
- end
122
-
123
- # Used to find questions for dependency linking
14
+ # Used to find questions for dependency linking
124
15
  def find_question_by_reference(ref_id)
125
16
  self.questions.detect{|q| q.reference_identifier == ref_id}
126
17
  end
127
18
 
128
- def yml_attrs
129
- instance_variables.sort - ["@parser", "@question_groups", "@questions", "@grid_answers", "@current_question_group", "@current_question", "@current_dependency"]
130
- end
131
- def to_yml
132
- out = [ %(#{@data_export_identifier}_#{@id}:) ]
133
- yml_attrs.each{|a| out << " #{a[1..-1]}: #{instance_variable_get(a).is_a?(String) ? "\"#{instance_variable_get(a)}\"" : instance_variable_get(a) }"}
134
- (out << nil ).join("\r\n")
135
- end
136
-
137
- def to_file
138
- File.open(self.parser.survey_sections_yml, File::CREAT|File::APPEND|File::WRONLY) {|f| f << to_yml}
139
- self.question_groups.compact.map(&:to_file)
140
- self.questions.compact.map(&:to_file)
141
- end
142
-
143
19
  end