questionable_answers 0.2.4
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +97 -0
- data/Rakefile +35 -0
- data/app/assets/javascripts/questionable/answers.js +2 -0
- data/app/assets/javascripts/questionable/application.js +15 -0
- data/app/assets/stylesheets/answers.css +29 -0
- data/app/assets/stylesheets/questionable.css +13 -0
- data/app/controllers/questionable/answers_controller.rb +62 -0
- data/app/controllers/questionable/application_controller.rb +5 -0
- data/app/helpers/questionable/application_helper.rb +4 -0
- data/app/models/questionable/answer.rb +16 -0
- data/app/models/questionable/assignment.rb +30 -0
- data/app/models/questionable/option.rb +9 -0
- data/app/models/questionable/question.rb +35 -0
- data/app/views/admin/options/_form.html.haml +8 -0
- data/app/views/layouts/questionable/application.html.erb +14 -0
- data/app/views/questionable/assignments/_form.html.haml +58 -0
- data/config/initializers/questionable.rb +3 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20130122192903_create_questionable_questions.rb +12 -0
- data/db/migrate/20130122193559_create_questionable_assignments.rb +14 -0
- data/db/migrate/20130122193820_create_questionable_options.rb +13 -0
- data/db/migrate/20130122194315_create_questionable_answers.rb +16 -0
- data/lib/questionable.rb +6 -0
- data/lib/questionable/admin/answers.rb +19 -0
- data/lib/questionable/admin/assignment.rb +24 -0
- data/lib/questionable/admin/option.rb +20 -0
- data/lib/questionable/admin/question.rb +46 -0
- data/lib/questionable/engine.rb +24 -0
- data/lib/questionable/version.rb +3 -0
- data/lib/questionable_surveys.rb +2 -0
- data/lib/tasks/questionable_tasks.rake +4 -0
- metadata +178 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8719cf883d31e3a10d08eb4ad619d0a258251a8
|
4
|
+
data.tar.gz: bfbac2001a3f41b68b8a136b18f65c7d7009cf5d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b9e4baba910c246013353e6ba1ea2eede7c6f110385678133e642b5118bb90966441324e08118ce7d396aa691c6f34d0a56d507acf8b79825d3ba60cd71a824b
|
7
|
+
data.tar.gz: 0063e26da0dd51193816c9683cb06a6672065342bde95bcc24b3bade6c2c0eaa37de069e6475ff0897b0d9d68cc5c478ee3a3221800e363d64f9be227b8a6cb6
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Bespoke Post
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
= Questionable
|
2
|
+
|
3
|
+
Questionable is a Rails engine that make it easier to create and answer surveys through a web interface.
|
4
|
+
|
5
|
+
You can create your questions and options through the included
|
6
|
+
{ActiveAdmin}[https://github.com/gregbell/active_admin] interface.
|
7
|
+
If ActiveAdmin is installed in your application, Questionable will automatically add admin pages.
|
8
|
+
|
9
|
+
Then you can use the included partial template and controller for displaying
|
10
|
+
the questions and recording your users' answers.
|
11
|
+
|
12
|
+
== Installation
|
13
|
+
|
14
|
+
Add Questionable to your Gemfile:
|
15
|
+
|
16
|
+
gem 'questionable_surveys'
|
17
|
+
|
18
|
+
or for the latest:
|
19
|
+
|
20
|
+
gem 'questionable_surveys', :git => 'git://github.com/bespokepost/questionable.git'
|
21
|
+
|
22
|
+
Then run:
|
23
|
+
|
24
|
+
bundle install
|
25
|
+
rake questionable:install:migrations
|
26
|
+
rake db:migrate
|
27
|
+
|
28
|
+
Add Questionable to your config/routes.rb:
|
29
|
+
|
30
|
+
mount Questionable::Engine, :at => 'questions'
|
31
|
+
|
32
|
+
Optionally add the following to app/assets/stylesheet/application.css:
|
33
|
+
|
34
|
+
*= require questionable
|
35
|
+
|
36
|
+
== Usage
|
37
|
+
|
38
|
+
=== Create some questions
|
39
|
+
|
40
|
+
Create one or more Questions. Supported input_types include select, multiselect,
|
41
|
+
radio, checkboxes, date, and string.
|
42
|
+
|
43
|
+
# input_type may be select, multiselect, radio, checkboxes, or string.
|
44
|
+
q = Questionable::Question.create(title: 'What is your favorite color?', input_type: 'select', note: 'This is important')
|
45
|
+
|
46
|
+
Add Options, unless input_type is 'string'
|
47
|
+
|
48
|
+
q.options.create(title: 'Red', position: 1)
|
49
|
+
q.options.create(title: 'Green', position: 2)
|
50
|
+
q.options.create(title: 'Blue', position: 3)
|
51
|
+
|
52
|
+
Questions must be assigned a 'subject' before they are used.
|
53
|
+
They subject can be either an object, via a polymorphic association,
|
54
|
+
or something general like "preferences", which we can pass here as a symbol or string.
|
55
|
+
|
56
|
+
e.g.
|
57
|
+
|
58
|
+
@product = Product.find(123)
|
59
|
+
Questionable::Assignment.create(question_id: q.id, subject: @product)
|
60
|
+
|
61
|
+
or
|
62
|
+
|
63
|
+
Questionable::Assignment.create(question_id: q.id, subject_type: 'preferences')
|
64
|
+
|
65
|
+
=== In your controller
|
66
|
+
|
67
|
+
Here's we fetch question-assignments for a particular symbol:
|
68
|
+
|
69
|
+
@assignments = Questionable::Assignment.with_subject(:preferences)
|
70
|
+
|
71
|
+
and here, for a product object:
|
72
|
+
|
73
|
+
@product = Product.find(params[:id])
|
74
|
+
@assignments = Questionable::Assignment.with_subject(@product)
|
75
|
+
|
76
|
+
=== In your view
|
77
|
+
|
78
|
+
With HAML
|
79
|
+
|
80
|
+
= render partial: 'questionable/assignments/form', locals: { assignments: @assignments }
|
81
|
+
|
82
|
+
Or ERB
|
83
|
+
|
84
|
+
<%= render partial: 'questionable/assignments/form', locals: { assignments: @assignments } %>
|
85
|
+
|
86
|
+
=== Running Tests
|
87
|
+
|
88
|
+
rake spec
|
89
|
+
|
90
|
+
== Author
|
91
|
+
|
92
|
+
Written by {Nick Urban}[https://github.com/nickurban/] at {Bespoke Post}[https://www.bespokepost.com/].
|
93
|
+
|
94
|
+
== Licence
|
95
|
+
|
96
|
+
This project uses the MIT-LICENSE.
|
97
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Questionable'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rspec/core'
|
31
|
+
require 'rspec/core/rake_task'
|
32
|
+
|
33
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
34
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
35
|
+
task :default => :spec
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
Place all the styles related to the matching controller here.
|
3
|
+
They will automatically be included in application.css.
|
4
|
+
*/
|
5
|
+
|
6
|
+
.questions-form .note { font-size: 0.8em; }
|
7
|
+
.questions-form .question-block { margin-bottom: 20px; }
|
8
|
+
|
9
|
+
.questions-form .select-month { width: 10em; }
|
10
|
+
.questions-form .select-day { width: 4em; }
|
11
|
+
.questions-form .select-year { width: 5em; }
|
12
|
+
|
13
|
+
.questions-form select {
|
14
|
+
width: 10em;
|
15
|
+
}
|
16
|
+
|
17
|
+
.questions-form .compact-input {
|
18
|
+
vertical-align: top;
|
19
|
+
}
|
20
|
+
|
21
|
+
.questions-form .question-and-note {
|
22
|
+
width: 320px;
|
23
|
+
}
|
24
|
+
|
25
|
+
.questions-form .question-and-note,
|
26
|
+
.questions-form .compact-input {
|
27
|
+
display: inline-block;
|
28
|
+
}
|
29
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_dependency "questionable/application_controller"
|
2
|
+
|
3
|
+
module Questionable
|
4
|
+
class AnswersController < ApplicationController
|
5
|
+
def create
|
6
|
+
answers = params[:answers]
|
7
|
+
|
8
|
+
unless current_user and answers.is_a?(Hash)
|
9
|
+
flash[:warn] = 'Something went wrong, please try again'
|
10
|
+
return redirect_to_back
|
11
|
+
end
|
12
|
+
|
13
|
+
# Answers should always be a hash, and the values should be arrays,
|
14
|
+
# even if the question input_type only supports a single answer.
|
15
|
+
|
16
|
+
answers.each do |assignment_id, answers|
|
17
|
+
assignment = Assignment.find(assignment_id)
|
18
|
+
assignment.answers.where(user_id: current_user.id).delete_all
|
19
|
+
|
20
|
+
input_type = assignment.question.input_type
|
21
|
+
|
22
|
+
if input_type == 'string'
|
23
|
+
message = answers.first || ''
|
24
|
+
assignment.answers.create(user_id: current_user.id, message: message[0..255])
|
25
|
+
elsif input_type == 'date'
|
26
|
+
date = answers.first
|
27
|
+
if date[:year].present? or date[:month].present? or date[:day].present?
|
28
|
+
if date[:year].present? and date[:month].present? and date[:day].present?
|
29
|
+
answer = assignment.answers.build(user_id: current_user.id, message: "#{date[:year]}-#{date[:month]}-#{date[:day]}")
|
30
|
+
if answer.date_answer.nil?
|
31
|
+
flash[:warn] = 'Could not save date. Invalid date.'
|
32
|
+
else
|
33
|
+
answer.save
|
34
|
+
end
|
35
|
+
else
|
36
|
+
flash[:warn] = 'Could not save date. You did not select all three fields.'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
else
|
40
|
+
option_ids = answers
|
41
|
+
option_ids.each do |oid|
|
42
|
+
unless oid.blank?
|
43
|
+
assignment.answers.create(user_id: current_user.id, option_id: oid)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
redirect_to_back
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def redirect_to_back
|
55
|
+
if request.env["HTTP_REFERER"].present?
|
56
|
+
redirect_to :back
|
57
|
+
else
|
58
|
+
redirect_to root_url
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Questionable
|
2
|
+
class Answer < ActiveRecord::Base
|
3
|
+
belongs_to :user
|
4
|
+
belongs_to :assignment
|
5
|
+
belongs_to :option
|
6
|
+
has_one :question, through: :assignment
|
7
|
+
|
8
|
+
def date_answer
|
9
|
+
return nil if message.nil?
|
10
|
+
|
11
|
+
self.message.to_date
|
12
|
+
rescue ArgumentError
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Questionable
|
2
|
+
class Assignment < ActiveRecord::Base
|
3
|
+
belongs_to :question
|
4
|
+
belongs_to :subject, polymorphic: true
|
5
|
+
|
6
|
+
has_many :answers
|
7
|
+
has_many :answered_options, through: :answers, source: :option
|
8
|
+
|
9
|
+
def self.with_subject(subject)
|
10
|
+
if subject.kind_of?(Symbol) or subject.kind_of?(String)
|
11
|
+
assignments = Questionable::Assignment.where(subject_type: subject)
|
12
|
+
else
|
13
|
+
assignments = Questionable::Assignment.where(
|
14
|
+
subject_type: subject.class.to_s,
|
15
|
+
subject_id: subject.id)
|
16
|
+
end
|
17
|
+
|
18
|
+
assignments.order(:position)
|
19
|
+
end
|
20
|
+
|
21
|
+
def answers_for_user(user)
|
22
|
+
self.answers.where(user_id: user.id)
|
23
|
+
end
|
24
|
+
|
25
|
+
# for ActiveAdmin
|
26
|
+
def display_name
|
27
|
+
"#{self.subject_type}#{self.subject_id}: #{self.question.title}"
|
28
|
+
end
|
29
|
+
end # End Assignment
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Questionable
|
2
|
+
class Question < ActiveRecord::Base
|
3
|
+
has_many :options
|
4
|
+
has_many :assignments
|
5
|
+
has_many :subjects, through: :assignments
|
6
|
+
has_many :answers, through: :assignments
|
7
|
+
|
8
|
+
validates_presence_of :title
|
9
|
+
|
10
|
+
def accepts_multiple_answers?
|
11
|
+
['checkboxes', 'multiselect'].include?(self.input_type)
|
12
|
+
end
|
13
|
+
|
14
|
+
def answers_for_user(user)
|
15
|
+
answers = self.answers.where(user_id: user.id)
|
16
|
+
answers.any? ? answers : [self.answers.build(user_id: user.id)]
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.with_subject(subject)
|
20
|
+
if subject.kind_of?(Symbol) or subject.kind_of?(String)
|
21
|
+
assignments = { subject_type: subject }
|
22
|
+
else
|
23
|
+
assignments = { subject_type: subject.class.to_s, subject_id: subject.id }
|
24
|
+
end
|
25
|
+
|
26
|
+
join_query = 'INNER JOIN questionable_assignments '
|
27
|
+
join_query += 'ON questionable_assignments.quest)ion_id = questionable_questions.id'
|
28
|
+
|
29
|
+
query = Questionable::Question.joins(join_query)
|
30
|
+
query = query.where(questionable_assignments: assignements)
|
31
|
+
query = query.order('questionable_assignments.position')
|
32
|
+
query
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Questionable</title>
|
5
|
+
<%= stylesheet_link_tag "questionable/application", :media => "all" %>
|
6
|
+
<%= javascript_include_tag "questionable/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
= form_tag questionable.answers_path, method: :post, class: 'questions-form' do
|
3
|
+
- assignments.each do |a|
|
4
|
+
.question-block{:id => "qa_#{a.id}", class: "question-#{a.question.id}"}
|
5
|
+
- q = a.question
|
6
|
+
|
7
|
+
.question-and-note
|
8
|
+
.question= q.title
|
9
|
+
.note= q.note if q.note
|
10
|
+
|
11
|
+
- selected_answers = a.answers_for_user(current_user)
|
12
|
+
- selected_option_ids = selected_answers.map(&:option_id)
|
13
|
+
- field = "answers[#{a.id}][]"
|
14
|
+
|
15
|
+
- if q.accepts_multiple_answers?
|
16
|
+
/ Some inputs can take multiple answers (namely multiselects and checkboxes)
|
17
|
+
- if q.input_type == 'checkboxes'
|
18
|
+
= hidden_field_tag field
|
19
|
+
- q.options.each do |opt|
|
20
|
+
%label.checkbox
|
21
|
+
= opt.title
|
22
|
+
= check_box_tag field, opt.id, selected_option_ids.include?(opt.id)
|
23
|
+
- elsif q.input_type == 'multiselect'
|
24
|
+
= select_tag field,
|
25
|
+
options_from_collection_for_select(q.options, 'id', 'title', selected_option_ids), multiple: true
|
26
|
+
|
27
|
+
- else
|
28
|
+
/ Most inputs just take a single answer
|
29
|
+
- if q.input_type == 'radio'
|
30
|
+
- q.options.each do |opt|
|
31
|
+
%label.radio
|
32
|
+
= opt.title
|
33
|
+
%input{type: :radio, name: field, value: opt.id, checked: selected_option_ids.first == opt.id}
|
34
|
+
=# radio_button_tag "answers[#{a.id}][]", opt.id, selected_option_ids.first
|
35
|
+
- else
|
36
|
+
.compact-input
|
37
|
+
- if q.input_type == 'select'
|
38
|
+
= select_tag "answers[#{a.id}][]",
|
39
|
+
options_from_collection_for_select(q.options, 'id', 'title', selected_option_ids.first), prompt: 'Choose an option'
|
40
|
+
- elsif q.input_type == 'string'
|
41
|
+
= text_field_tag field, selected_answers.first.try(:message)
|
42
|
+
- elsif q.input_type == 'date'
|
43
|
+
=# select_date nil, field, order: [:month, :day, :year]
|
44
|
+
=# date_select (Date.today - 20.years), field, order: [:month, :day, :year]
|
45
|
+
|
46
|
+
- date = selected_answers.first.try(:date_answer)
|
47
|
+
|
48
|
+
.date-fields
|
49
|
+
= select_month date, {prompt: date.blank?}, name: "#{field}[month]", class: 'select-month'
|
50
|
+
= select_day date, {prompt: date.blank?}, name: "#{field}[day]", class: 'select-day'
|
51
|
+
= select_year date,
|
52
|
+
{prompt: date.blank?, start_year: (Date.today-13.years).year, end_year: (Date.today-70.years).year},
|
53
|
+
name: "#{field}[year]", class: 'select-year'
|
54
|
+
|
55
|
+
.form-actions
|
56
|
+
- label = local_assigns.has_key?(:submit_label) ? submit_label : 'Save'
|
57
|
+
= submit_tag label, class: 'btn'
|
58
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateQuestionableQuestions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :questionable_questions do |t|
|
4
|
+
t.string :category
|
5
|
+
t.string :title
|
6
|
+
t.string :note
|
7
|
+
t.string :input_type # string, select, radio, checkboxes, multiselect, etc. statement (checkbox)
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateQuestionableAssignments < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :questionable_assignments do |t|
|
4
|
+
t.integer :question_id
|
5
|
+
t.integer :subject_id
|
6
|
+
t.string :subject_type
|
7
|
+
t.integer :position
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :questionable_assignments, [:subject_type, :subject_id, :position], :name => 'index_questionable_assignments_on_subject_and_position'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateQuestionableOptions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :questionable_options do |t|
|
4
|
+
t.integer :question_id
|
5
|
+
t.string :title
|
6
|
+
t.string :note
|
7
|
+
t.integer :position
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
add_index :questionable_options, [:question_id, :position]
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateQuestionableAnswers < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :questionable_answers do |t|
|
4
|
+
t.integer :user_id
|
5
|
+
t.integer :assignment_id
|
6
|
+
t.integer :option_id # which option was chosen as the answer
|
7
|
+
t.string :message # a freeform message e.g. "Other"
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :questionable_answers, :user_id
|
13
|
+
add_index :questionable_answers, :assignment_id
|
14
|
+
add_index :questionable_answers, :option_id
|
15
|
+
end
|
16
|
+
end
|
data/lib/questionable.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
if defined?(ActiveAdmin)
|
2
|
+
ActiveAdmin.register Questionable::Answer, :as => 'Answers' do
|
3
|
+
menu :label => 'Answers', :parent => 'Questionable'
|
4
|
+
|
5
|
+
filter :user_email, :as => :string
|
6
|
+
filter :assignment_sources
|
7
|
+
filter :created_at
|
8
|
+
filter :updated_at
|
9
|
+
|
10
|
+
index do
|
11
|
+
column(:id) { |a| link_to a.id, admin_answer_path(a) }
|
12
|
+
column(:user)
|
13
|
+
column(:assignment)
|
14
|
+
column(:option)
|
15
|
+
column(:message)
|
16
|
+
default_actions
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
if defined?(ActiveAdmin)
|
2
|
+
ActiveAdmin.register Questionable::Assignment, :as => 'Assignments', :sort_order => 'source_type, source_id, position' do
|
3
|
+
menu :label => 'Assignments', :parent => 'Questionable'
|
4
|
+
|
5
|
+
index do
|
6
|
+
column(:id) { |a| link_to a.id, admin_assignment_path(a.id) }
|
7
|
+
column(:subject) { |a| a.subject_id ? a.subject : a.subject_type }
|
8
|
+
column :position
|
9
|
+
column(:question) { |a| a.question.title }
|
10
|
+
column :created_at
|
11
|
+
column :updated_at
|
12
|
+
end
|
13
|
+
|
14
|
+
form do |f|
|
15
|
+
f.inputs do
|
16
|
+
f.input :question
|
17
|
+
f.input :subject_type
|
18
|
+
f.input :subject_id, :as => :number
|
19
|
+
f.input :position
|
20
|
+
end
|
21
|
+
f.actions
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
if defined?(ActiveAdmin)
|
2
|
+
# NOTE: This ":as" option determines the names of the routes generated
|
3
|
+
ActiveAdmin.register Questionable::Option, :as => 'Options' do
|
4
|
+
menu :label => 'Options', :parent => 'Questionable'
|
5
|
+
|
6
|
+
controller do
|
7
|
+
def create
|
8
|
+
create!(location: request.referrer)
|
9
|
+
end
|
10
|
+
|
11
|
+
def update
|
12
|
+
update!(location: admin_question_path(resource.question))
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
destroy!(location: admin_question_path(resource.question))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
if defined?(ActiveAdmin)
|
2
|
+
# NOTE: This ":as" option determines the names of the routes generated
|
3
|
+
ActiveAdmin.register Questionable::Question, :as => 'Questions' do
|
4
|
+
menu :label => 'Questions', :parent => 'Questionable'
|
5
|
+
|
6
|
+
form do |f|
|
7
|
+
f.inputs do
|
8
|
+
f.input :title
|
9
|
+
f.input :note
|
10
|
+
f.input :category
|
11
|
+
f.input :input_type, :as => :select,
|
12
|
+
:collection => %w(select radio checkboxes multiselect date string statement), :include_blank => false
|
13
|
+
end
|
14
|
+
f.actions
|
15
|
+
end
|
16
|
+
|
17
|
+
show do |q|
|
18
|
+
attributes_table do
|
19
|
+
row :id
|
20
|
+
row :title
|
21
|
+
row :note
|
22
|
+
row :category
|
23
|
+
row :input_type
|
24
|
+
end
|
25
|
+
|
26
|
+
panel 'Options', class: 'options' do
|
27
|
+
table_for(q.options) do
|
28
|
+
column(:id) { |o| link_to o.id, admin_option_path(o) }
|
29
|
+
column :title
|
30
|
+
column :note
|
31
|
+
column :position
|
32
|
+
column(:actions) do |o|
|
33
|
+
link_to('Edit', edit_admin_option_path(o)) + ' | ' +
|
34
|
+
link_to('Delete', admin_option_path(o), :method => :delete)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
panel 'Add Option', class: 'add-option' do
|
41
|
+
render partial: 'admin/options/form', locals: { question: q }
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'stringex'
|
2
|
+
|
3
|
+
module Questionable
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
isolate_namespace Questionable
|
6
|
+
|
7
|
+
initializer :questionable do
|
8
|
+
if defined?(ActiveAdmin)
|
9
|
+
dir = File.dirname(__FILE__) + '/admin'
|
10
|
+
# Prepend the load paths, which should allow this to be overridden by an app.
|
11
|
+
# If we wanted to prevent an override, we could append dir to load_paths instead.
|
12
|
+
ActiveAdmin.application.load_paths.unshift dir
|
13
|
+
#ActiveAdmin.application.load_paths += dir
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
config.generators do |g|
|
18
|
+
g.test_framework :rspec, :view_specs => false, :fixture => false
|
19
|
+
g.fixture_replacement :factory_girl, :dir => "spec/factories"
|
20
|
+
g.assets false
|
21
|
+
g.helper false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: questionable_answers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nick Urban, Dorian Marié
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.2.11
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.2.11
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: haml
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: formtastic
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: stringex
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: factory_girl_rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Makes it easy to add and edit forms programatically, specifying select,
|
112
|
+
radio, checkbox, or string input, and recordings users' answers. Questions can be
|
113
|
+
associated with specific objects or with string labels. A form template and controller
|
114
|
+
are including for displaying questions and recording answers, and ActiveAdmin is
|
115
|
+
supported for editing the questions and options on the back-end.
|
116
|
+
email:
|
117
|
+
- nick@nickurban.com, dorian@bespokepost.com
|
118
|
+
executables: []
|
119
|
+
extensions: []
|
120
|
+
extra_rdoc_files: []
|
121
|
+
files:
|
122
|
+
- MIT-LICENSE
|
123
|
+
- README.rdoc
|
124
|
+
- Rakefile
|
125
|
+
- app/assets/javascripts/questionable/answers.js
|
126
|
+
- app/assets/javascripts/questionable/application.js
|
127
|
+
- app/assets/stylesheets/answers.css
|
128
|
+
- app/assets/stylesheets/questionable.css
|
129
|
+
- app/controllers/questionable/answers_controller.rb
|
130
|
+
- app/controllers/questionable/application_controller.rb
|
131
|
+
- app/helpers/questionable/application_helper.rb
|
132
|
+
- app/models/questionable/answer.rb
|
133
|
+
- app/models/questionable/assignment.rb
|
134
|
+
- app/models/questionable/option.rb
|
135
|
+
- app/models/questionable/question.rb
|
136
|
+
- app/views/admin/options/_form.html.haml
|
137
|
+
- app/views/layouts/questionable/application.html.erb
|
138
|
+
- app/views/questionable/assignments/_form.html.haml
|
139
|
+
- config/initializers/questionable.rb
|
140
|
+
- config/routes.rb
|
141
|
+
- db/migrate/20130122192903_create_questionable_questions.rb
|
142
|
+
- db/migrate/20130122193559_create_questionable_assignments.rb
|
143
|
+
- db/migrate/20130122193820_create_questionable_options.rb
|
144
|
+
- db/migrate/20130122194315_create_questionable_answers.rb
|
145
|
+
- lib/questionable.rb
|
146
|
+
- lib/questionable/admin/answers.rb
|
147
|
+
- lib/questionable/admin/assignment.rb
|
148
|
+
- lib/questionable/admin/option.rb
|
149
|
+
- lib/questionable/admin/question.rb
|
150
|
+
- lib/questionable/engine.rb
|
151
|
+
- lib/questionable/version.rb
|
152
|
+
- lib/questionable_surveys.rb
|
153
|
+
- lib/tasks/questionable_tasks.rake
|
154
|
+
homepage: https://github.com/bespokepost/questionable
|
155
|
+
licenses:
|
156
|
+
- MIT
|
157
|
+
metadata: {}
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 2.2.2
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: Rails engine that programatically generates surveys.
|
178
|
+
test_files: []
|