Skip to content
Build surveys and record answers using ActiveRecord
Ruby Shell
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bin
lib
spec
.gitignore
.rspec
.travis.yml
Gemfile
LICENSE.txt
README.md
Rakefile
active_record_survey.gemspec
rspec_rvm

README.md

Gem Version Build Status

ActiveRecordSurvey

An attempt at a more versatile data structure for making and taking surveys.

This gem tries to be as unopinionated as possible on the peripheral details on how you implement a survey.

The goal is to give a simple interface for creating surveys and validating the answers given to them.

Release Notes

0.1.36

  • ActiveRecordSurvey::Node::Answer#build_link and ActiveRecordSurvey::Node::Answer#remove_link moved to ActiveRecordSurvey::Node so that questions can directly follow one another without answers
  • Implemented ActiveRecordSurvey::Node::Question#next_questions to return all questions that follow either directly or through answers

0.1.33

  • ActiveRecordSurvey::Node::Answer#sibling_index method for setting position as well

0.1.32

  • ActiveRecordSurvey::Node::Answer#sibling_index for regular answers and chained answers

0.1.31

  • ActiveRecordSurvey::Node::Answer#move_up and ActiveRecordSurvey::Node::Answer#move_down implemented so you can change the position of answers relative to one another i both branching and chained types. I am not happy yet with this. AwesomeNestedSet seems to require nodes exist before moving them which is a limitation I'd like to not have.

0.1.30

  • ActiveRecordSurvey::Node::Question now throws ArgumentError if answers of different types are added to it

0.1.29

  • ActiveRecordSurvey::Node::Answer now cleans up associated node_maps on destruction
  • extending/including ActiveRecordSurvey::Answer::Chained now rebuilds broken links in the parent<->child node_maps if a middle node_map is destroyed

0.1.26

  • Major refactor of answer#build_link and answer#remove_link
  • ActiveRecordSurvey::Node now has a direct reference to its survey. Don't forget to run the install task Update_0_1_26_ActiveRecordSurvey
  • survey#build_question removed, no longer needed, just use survey.questions.build

0.1.24

  • Refactored class ActiveRecordSurvey::Node::Answer::Chain to module ActiveRecordSurvey::Node::Answer::Chained - this functionality makes way more sense implemented as a module.

0.1.23

  • Added ActiveRecordSurvey::Node::Answer::Chain for common chainable interface for answers

0.1.22

  • answer#remove_link cleaned up so it can be understood

0.1.21

  • answer#build_link now detects and throws an error when a infinite loop is added

0.1.20

  • answer#remove_link wasn't correct. Fixed and added unit tests

0.1.15

  • Don't consider instance_nodes marked for destruction when validating

0.1.14

  • build_question now only accepts a question
  • Exceptions added

0.1.13

  • Added Question#build_answer and Answer#build_link to make survey creation possible without dealing with internal nodes

Installation

Add this line to your application's Gemfile:

gem 'active_record_survey'

And then execute:

$ bundle

Or install it yourself as:

$ gem install active_record_survey

Installation

rails generate active_record_survey:active_record

Usage

See the spec file for more detailed usage.

Please be aware that the default gem does not prescribe how your ActiveRecordSurvey::Node should store text - that's up for you to implement.

See the spec for a sample implementation or ActiveRecordSurveyApi for a fully translatable implementation using the Globalize gem.

The usage below with :text => "" will not actually work unless you implement :text

Build a basic survey

# Building surveys
@survey = ActiveRecordSurvey::Survey.new()

@q1 = @survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #1", :survey => @survey)
@q1_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #1")
@q1_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #2")
@q1_a3 = ActiveRecordSurvey::Node::Answer.new(:text => "Q1 Answer #3")
@q1.build_answer(@q1_a1)
@q1.build_answer(@q1_a2)
@q1.build_answer(@q1_a3)

@q2 = @survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #2", :survey => @survey)
@q2_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q2 Answer #1")
@q2_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q2 Answer #2")
@q2.build_answer(@q2_a1)
@q2.build_answer(@q2_a2)

@q3 = @survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #3", :survey => @survey)
@q3_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q3 Answer #1")
@q3_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q3 Answer #2")
@q3.build_answer(@q3_a1)
@q3.build_answer(@q3_a2)

@q4 = @survey.questions.build(:type => "ActiveRecordSurvey::Node::Question", :text => "Question #4", :survey => @survey)
@q4_a1 = ActiveRecordSurvey::Node::Answer.new(:text => "Q4 Answer #1")
@q4_a2 = ActiveRecordSurvey::Node::Answer.new(:text => "Q4 Answer #2")
@q4.build_answer(@q4_a1)
@q4.build_answer(@q4_a2)

# Link up Q1
@q1_a1.build_link(@q2)
@q1_a2.build_link(@q3)
@q1_a3.build_link(@q4)

# Link up Q2
@q2_a1.build_link(@q4)
@q2_a2.build_link(@q3)

# Link up Q3
@q3_a1.build_link(@q4)
@q3_a2.build_link(@q4)

# Commit everything to the database!
@survey.save

The will build a survey with the following node structure.

alt tag

Answer Types

A number of different answer types are implemented by default.

Default

ActiveRecordSurvey::Node::Answer

The default answer type (think of it like a radio question) - this is currently the only answer type you can attach to a question so that depending on the answer given you can branch to a different question.

Boolean

ActiveRecordSurvey::Node::Answer::Boolean

True/False (0/1 actually... think of it like a checkbox) answer types.

Rank

ActiveRecordSurvey::Node::Answer::Rank

Rankable (answer value is 1..NUM_ANSWERS) to rank the answers in relation to one another.

Scale

ActiveRecordSurvey::Node::Answer::Scale

Scale (answer value is a min/max on a scale of A->B) where you can specificy each answer on a scale

Text

ActiveRecordSurvey::Node::Answer::Text

Textual answer to a question (e.g. please tell us what you thinik...)

Answer Validation

Enforcing answer criteria is accomplished by attaching validation nodes to ActiveRecordSurvey::Node records.

When a survey is taken validations are automatically run and their criteria is enforced.

A number of validations are already implemented by default.

You can implement your own validation by extending the ActiveRecordSurvey::ValidationNode class.

MaximumAnswer

ActiveRecordSurvey::ValidationNode::MaximumAnswer

These nodes should only be attached to nodes which extend ActiveRecordSurvey::Node::Question nodes.

Ensures that a maximum numer of answers have been selected. For chained answer nodes such as ActiveRecordSurvey::Node::Answer::Boolean,ActiveRecordSurvey::Node::Answer::Rank, and ActiveRecordSurvey::Node::Answer::Scale it enforces a maximum amount that be answered.

<a id=answer_minimum_answer"">

MinimumAnswer

ActiveRecordSurvey::ValidationNode::MinimumAnswer

These nodes should only be attached to nodes which extend ActiveRecordSurvey::Node::Question nodes.

Ensures that a minimum numer of answers have been selected. For chained answer nodes such as ActiveRecordSurvey::Node::Answer::Boolean,ActiveRecordSurvey::Node::Answer::Rank, and ActiveRecordSurvey::Node::Answer::Scale it enforces a minimum amount that can be answered.

MaximumValue

ActiveRecordSurvey::ValidationNode::MaximumValue

These nodes should only be attached to nodes which extend ActiveRecordSurvey::Node::Answer nodes which record an scalar answer value such as ActiveRecordSurvey::Node::Answer::Scale.

Ensures that a minimum scalar value has been entered.

MinimumValue

ActiveRecordSurvey::ValidationNode::MinimumValue

These nodes should only be attached to nodes which extend ActiveRecordSurvey::Node::Answer nodes which record an scalar answer value such as ActiveRecordSurvey::Node::Answer::Scale.

Ensures that a maximum scalar value has been entered.

MaximumLength

ActiveRecordSurvey::ValidationNode::MaximumLength

These nodes should only be attached to nodes which extend ActiveRecordSurvey::Node::Answer nodes nodes which record a text value such as ActiveRecordSurvey::Node::Answer::Text.

Ensures that a maximum amount of text has been answered.

MinimumLength

ActiveRecordSurvey::ValidationNode::MinimumLength

These nodes should only be attached to nodes which extend ActiveRecordSurvey::Node::Answer nodes nodes which record a text value such as ActiveRecordSurvey::Node::Answer::Text.

Ensures that a minimum amount of text has been answered.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/butchmarshall/active_record_survey.

License

The gem is available as open source under the terms of the MIT License.

You can’t perform that action at this time.