active_record_survey 0.1.28 → 0.1.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/lib/active_record_survey/node/answer/boolean.rb +2 -1
- data/lib/active_record_survey/node/answer/chained.rb +40 -17
- data/lib/active_record_survey/node/answer/rank.rb +2 -1
- data/lib/active_record_survey/node/answer/scale.rb +2 -1
- data/lib/active_record_survey/node/answer/text.rb +2 -1
- data/lib/active_record_survey/node.rb +2 -2
- data/lib/active_record_survey/node_map.rb +2 -2
- data/lib/active_record_survey/version.rb +1 -1
- data/spec/active_record_survey/node/answer/boolean_spec.rb +21 -0
- data/spec/active_record_survey/node/answer_spec.rb +25 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2afb9c3325db53de73001c5d6f59325c1358857
|
4
|
+
data.tar.gz: 79c0edcfa55069372786f9aec408e679f4216752
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b82564a960e98748f511fe5aa26b8b76b1b1a71c6b993f18bdf979631cce2dcf714f008b5da9a1cd7176bb03088bca5ad6c17842df6f494ab225f5f4dea357a
|
7
|
+
data.tar.gz: 7ab230a31470113797bd349e784e24a500562ae4cd651e35b4e476f79c39712bcb30ab029cc8b66cfbade0320025593eb4436ef36516c64429ac2fe1180f77be
|
data/README.md
CHANGED
@@ -12,6 +12,10 @@ The goal is to give a simple interface for creating surveys and validating the a
|
|
12
12
|
Release Notes
|
13
13
|
============
|
14
14
|
|
15
|
+
**0.1.29**
|
16
|
+
- `ActiveRecordSurvey::Node::Answer` now cleans up associated node_maps on destruction
|
17
|
+
- extending/including `ActiveRecordSurvey::Answer::Chained` now rebuilds broken links in the parent<->child node_maps if a middle node_map is destroyed
|
18
|
+
|
15
19
|
**0.1.26**
|
16
20
|
- Major refactor of answer#build_link and answer#remove_link
|
17
21
|
- `ActiveRecordSurvey::Node` now has a direct reference to its survey. Don't forget to run the install task Update_0_1_26_ActiveRecordSurvey
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module ActiveRecordSurvey
|
2
2
|
# Boolean answers can have values 0|1
|
3
3
|
class Node::Answer::Boolean < Node::Answer
|
4
|
-
include Answer::Chained
|
4
|
+
include Answer::Chained::InstanceMethods
|
5
|
+
extend Answer::Chained::ClassMethods
|
5
6
|
|
6
7
|
# Only boolean values
|
7
8
|
def validate_instance_node(instance_node)
|
@@ -1,28 +1,51 @@
|
|
1
1
|
module ActiveRecordSurvey
|
2
2
|
class Answer
|
3
3
|
module Chained
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module ClassMethods
|
5
|
+
def self.extended(base)
|
6
|
+
base.before_destroy :before_destroy_rebuild_node_map, prepend: true # prepend is important! otherwise dependent: :destroy on node<->node_map relation is executed first and no records!
|
7
|
+
end
|
8
|
+
end
|
7
9
|
|
8
|
-
|
10
|
+
module InstanceMethods
|
11
|
+
# Chain nodes are different - they must find the final answer node added and add to it
|
12
|
+
def build_answer(question_node)
|
13
|
+
self.survey = question_node.survey
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
question_node_maps
|
14
|
-
|
15
|
+
question_node_maps = self.survey.node_maps.select { |i| i.node == question_node && !i.marked_for_destruction? }
|
16
|
+
|
17
|
+
# No node_maps exist yet from this question
|
18
|
+
if question_node_maps.length === 0
|
19
|
+
# Build our first node-map
|
20
|
+
question_node_maps << self.survey.node_maps.build(:node => question_node, :survey => self.survey)
|
21
|
+
end
|
15
22
|
|
16
|
-
|
23
|
+
last_answer_in_chain = (question_node.answers.last || question_node)
|
24
|
+
|
25
|
+
# Each instance of this question needs the answer hung from it
|
26
|
+
self.survey.node_maps.select { |i|
|
27
|
+
i.node == last_answer_in_chain
|
28
|
+
}.each { |node_map|
|
29
|
+
node_map.children << self.survey.node_maps.build(:node => self, :survey => self.survey)
|
30
|
+
}
|
31
|
+
|
32
|
+
true
|
33
|
+
end
|
17
34
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
}.each { |node_map|
|
22
|
-
node_map.children << self.survey.node_maps.build(:node => self, :survey => self.survey)
|
23
|
-
}
|
35
|
+
private
|
36
|
+
# Before a node is destroyed, will re-build the node_map links from parent to child if they exist
|
37
|
+
def before_destroy_rebuild_node_map
|
24
38
|
|
25
|
-
|
39
|
+
# All the node_maps from this node
|
40
|
+
self.survey.node_maps.select { |i|
|
41
|
+
i.node == self
|
42
|
+
}.each { |node_map|
|
43
|
+
# Remap all of this nodes children to the parent
|
44
|
+
node_map.children.each { |child|
|
45
|
+
node_map.parent.children << child
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
26
49
|
end
|
27
50
|
end
|
28
51
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module ActiveRecordSurvey
|
2
2
|
# Rank in relation to parent/children of ActiveRecordSurvey::Node::Answer::Rank
|
3
3
|
class Node::Answer::Rank < Node::Answer
|
4
|
-
include Answer::Chained
|
4
|
+
include Answer::Chained::InstanceMethods
|
5
|
+
extend Answer::Chained::ClassMethods
|
5
6
|
|
6
7
|
# Accept integer or empty values
|
7
8
|
# Must be within range of the number of ranking nodes
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module ActiveRecordSurvey
|
2
2
|
# Can hold a value on a scale (e.g. from 0-10)
|
3
3
|
class Node::Answer::Scale < Node::Answer
|
4
|
-
include Answer::Chained
|
4
|
+
include Answer::Chained::InstanceMethods
|
5
|
+
extend Answer::Chained::ClassMethods
|
5
6
|
|
6
7
|
# Accept integer, float, or empty values
|
7
8
|
def validate_instance_node(instance_node)
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module ActiveRecordSurvey
|
2
2
|
# Text answers are... text answers
|
3
3
|
class Node::Answer::Text < Node::Answer
|
4
|
-
include Answer::Chained
|
4
|
+
include Answer::Chained::InstanceMethods
|
5
|
+
extend Answer::Chained::ClassMethods
|
5
6
|
|
6
7
|
# Text answers are considered answered if they have text entered
|
7
8
|
def is_answered_for_instance?(instance)
|
@@ -2,8 +2,8 @@ module ActiveRecordSurvey
|
|
2
2
|
class Node < ::ActiveRecord::Base
|
3
3
|
self.table_name = "active_record_survey_nodes"
|
4
4
|
belongs_to :survey, :class_name => "ActiveRecordSurvey::Survey", :foreign_key => :active_record_survey_id
|
5
|
-
has_many :node_maps, :class_name => "ActiveRecordSurvey::NodeMap", :foreign_key => :active_record_survey_node_id, autosave: true
|
6
|
-
has_many :node_validations, :class_name => "ActiveRecordSurvey::NodeValidation", :foreign_key => :active_record_survey_node_id, autosave: true
|
5
|
+
has_many :node_maps, :class_name => "ActiveRecordSurvey::NodeMap", :foreign_key => :active_record_survey_node_id, autosave: true, dependent: :destroy
|
6
|
+
has_many :node_validations, :class_name => "ActiveRecordSurvey::NodeValidation", :foreign_key => :active_record_survey_node_id, autosave: true, dependent: :destroy
|
7
7
|
has_many :instance_nodes, :class_name => "ActiveRecordSurvey::InstanceNode", :foreign_key => :active_record_survey_node_id
|
8
8
|
|
9
9
|
# All the answer nodes that follow from this node
|
@@ -25,9 +25,9 @@ module ActiveRecordSurvey
|
|
25
25
|
}
|
26
26
|
|
27
27
|
result = {}
|
28
|
-
result.merge!({ :id => self.id, :node_id => self.node.id }) if !options[:no_ids]
|
28
|
+
result.merge!({ :id => self.id, :node_id => ((self.node.respond_to?(:id))? self.node.id : "") }) if !options[:no_ids] && !self.node.nil?
|
29
29
|
result.merge!({
|
30
|
-
:type => self.node.class.to_s,
|
30
|
+
:type => ((!self.node.nil?)? self.node.class.to_s : ""),
|
31
31
|
:children => c.collect { |i|
|
32
32
|
i.as_map(options)
|
33
33
|
}
|
@@ -1,6 +1,27 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ActiveRecordSurvey::Node::Answer::Boolean, :boolean_spec => true do
|
4
|
+
describe '#destroy', :focus => true do
|
5
|
+
it 'should re-link broken chains' do
|
6
|
+
survey = ActiveRecordSurvey::Survey.new()
|
7
|
+
q1 = ActiveRecordSurvey::Node::Question.new(:text => "Question #1", :survey => survey)
|
8
|
+
q1_a1 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Q1 Answer #1")
|
9
|
+
q1_a2 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Q1 Answer #2")
|
10
|
+
q1_a3 = ActiveRecordSurvey::Node::Answer::Boolean.new(:text => "Q1 Answer #3")
|
11
|
+
q1.build_answer(q1_a1)
|
12
|
+
q1.build_answer(q1_a2)
|
13
|
+
q1.build_answer(q1_a3)
|
14
|
+
survey.save
|
15
|
+
|
16
|
+
expect(survey.as_map(no_ids: true)).to eq([{"text"=>"Question #1", :type=>"ActiveRecordSurvey::Node::Question", :children=>[{"text"=>"Q1 Answer #1", :type=>"ActiveRecordSurvey::Node::Answer::Boolean", :children=>[{"text"=>"Q1 Answer #2", :type=>"ActiveRecordSurvey::Node::Answer::Boolean", :children=>[{"text"=>"Q1 Answer #3", :type=>"ActiveRecordSurvey::Node::Answer::Boolean", :children=>[]}]}]}]}])
|
17
|
+
|
18
|
+
q1_a2.destroy
|
19
|
+
survey.reload # reload seems to be necessary
|
20
|
+
|
21
|
+
expect(survey.as_map(no_ids: true)).to eq([{"text"=>"Question #1", :type=>"ActiveRecordSurvey::Node::Question", :children=>[{"text"=>"Q1 Answer #1", :type=>"ActiveRecordSurvey::Node::Answer::Boolean", :children=>[{"text"=>"Q1 Answer #3", :type=>"ActiveRecordSurvey::Node::Answer::Boolean", :children=>[]}]}]}])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
4
25
|
describe 'a boolean survey is' do
|
5
26
|
before(:all) do
|
6
27
|
@survey = ActiveRecordSurvey::Survey.new()
|
@@ -1,6 +1,30 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ActiveRecordSurvey::Node::Answer, :answer_spec => true do
|
4
|
+
# When answer nodes are deleted should:
|
5
|
+
# - Clean upp node_maps
|
6
|
+
# - If chained, build a chain from parent -> child after removing self
|
7
|
+
describe '#destroy' do
|
8
|
+
it 'should clean up node maps' do
|
9
|
+
survey = ActiveRecordSurvey::Survey.new()
|
10
|
+
q1 = ActiveRecordSurvey::Node::Question.new(:text => "Question #1", :survey => survey)
|
11
|
+
q1_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #1")
|
12
|
+
q1_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #2")
|
13
|
+
q1_a3 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #3")
|
14
|
+
q1.build_answer(q1_a1)
|
15
|
+
q1.build_answer(q1_a2)
|
16
|
+
q1.build_answer(q1_a3)
|
17
|
+
survey.save
|
18
|
+
|
19
|
+
expect(survey.as_map(no_ids: true)).to eq([{"text"=>"Question #1", :type=>"ActiveRecordSurvey::Node::Question", :children=>[{"text"=>"Q1 Answer #1", :type=>"ActiveRecordSurvey::Node::Answer", :children=>[]}, {"text"=>"Q1 Answer #2", :type=>"ActiveRecordSurvey::Node::Answer", :children=>[]}, {"text"=>"Q1 Answer #3", :type=>"ActiveRecordSurvey::Node::Answer", :children=>[]}]}])
|
20
|
+
|
21
|
+
q1_a2.destroy
|
22
|
+
survey.reload
|
23
|
+
|
24
|
+
expect(survey.as_map(no_ids: true)).to eq([{"text"=>"Question #1", :type=>"ActiveRecordSurvey::Node::Question", :children=>[{"text"=>"Q1 Answer #1", :type=>"ActiveRecordSurvey::Node::Answer", :children=>[]}, {"text"=>"Q1 Answer #3", :type=>"ActiveRecordSurvey::Node::Answer", :children=>[]}]}])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
4
28
|
describe "#build_link" do
|
5
29
|
it 'should not have to be saved to produce a valid #as_map' do
|
6
30
|
survey = ActiveRecordSurvey::Survey.new()
|
@@ -83,7 +107,7 @@ describe ActiveRecordSurvey::Node::Answer, :answer_spec => true do
|
|
83
107
|
expect{q3_a1.build_link(q1)}.to raise_error(RuntimeError) # This should throw exception
|
84
108
|
end
|
85
109
|
|
86
|
-
it 'should keep consistent number of nodes after calling #remove_link and #build_link'
|
110
|
+
it 'should keep consistent number of nodes after calling #remove_link and #build_link' do
|
87
111
|
survey = FactoryGirl.build(:simple_survey)
|
88
112
|
survey.save
|
89
113
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_survey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.29
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Butch Marshall
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -194,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
194
|
version: '0'
|
195
195
|
requirements: []
|
196
196
|
rubyforge_project:
|
197
|
-
rubygems_version: 2.6
|
197
|
+
rubygems_version: 2.4.6
|
198
198
|
signing_key:
|
199
199
|
specification_version: 4
|
200
200
|
summary: Surveys using activerecord
|