unique_rapidfire 1.0.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/MIT-LICENSE +20 -0
- data/README.md +199 -0
- data/Rakefile +36 -0
- data/app/assets/javascripts/rapidfire/application.js +12 -0
- data/app/assets/stylesheets/rapidfire/application.css +22 -0
- data/app/controllers/rapidfire/answer_groups_controller.rb +34 -0
- data/app/controllers/rapidfire/application_controller.rb +11 -0
- data/app/controllers/rapidfire/question_groups_controller.rb +48 -0
- data/app/controllers/rapidfire/questions_controller.rb +58 -0
- data/app/helpers/rapidfire/application_helper.rb +12 -0
- data/app/models/rapidfire/answer.rb +18 -0
- data/app/models/rapidfire/answer_group.rb +12 -0
- data/app/models/rapidfire/question.rb +44 -0
- data/app/models/rapidfire/question_group.rb +10 -0
- data/app/models/rapidfire/questions/checkbox.rb +21 -0
- data/app/models/rapidfire/questions/date.rb +16 -0
- data/app/models/rapidfire/questions/long.rb +6 -0
- data/app/models/rapidfire/questions/numeric.rb +21 -0
- data/app/models/rapidfire/questions/radio.rb +6 -0
- data/app/models/rapidfire/questions/select.rb +19 -0
- data/app/models/rapidfire/questions/short.rb +6 -0
- data/app/serializers/rapidfire/question_result_serializer.rb +15 -0
- data/app/services/rapidfire/answer_group_builder.rb +48 -0
- data/app/services/rapidfire/base_service.rb +21 -0
- data/app/services/rapidfire/question_form.rb +85 -0
- data/app/services/rapidfire/question_group_results.rb +29 -0
- data/app/services/rapidfire/question_result.rb +11 -0
- data/app/views/rapidfire/answer_groups/new.html.erb +11 -0
- data/app/views/rapidfire/answers/_checkbox.html.erb +11 -0
- data/app/views/rapidfire/answers/_date.html.erb +4 -0
- data/app/views/rapidfire/answers/_errors.html.erb +7 -0
- data/app/views/rapidfire/answers/_long.html.erb +4 -0
- data/app/views/rapidfire/answers/_numeric.html.erb +4 -0
- data/app/views/rapidfire/answers/_radio.html.erb +9 -0
- data/app/views/rapidfire/answers/_select.html.erb +4 -0
- data/app/views/rapidfire/answers/_short.html.erb +4 -0
- data/app/views/rapidfire/question_groups/_form.html.erb +15 -0
- data/app/views/rapidfire/question_groups/_question_group.html.erb +18 -0
- data/app/views/rapidfire/question_groups/index.html.erb +23 -0
- data/app/views/rapidfire/question_groups/new.html.erb +1 -0
- data/app/views/rapidfire/question_groups/results.html.erb +32 -0
- data/app/views/rapidfire/questions/_form.html.erb +40 -0
- data/app/views/rapidfire/questions/_question.html.erb +9 -0
- data/app/views/rapidfire/questions/edit.html.erb +1 -0
- data/app/views/rapidfire/questions/index.html.erb +21 -0
- data/app/views/rapidfire/questions/new.html.erb +1 -0
- data/config/database.yml +8 -0
- data/config/routes.rb +10 -0
- data/db/migrate/20130502170733_create_rapidfire_question_groups.rb +8 -0
- data/db/migrate/20130502195310_create_rapidfire_questions.rb +15 -0
- data/db/migrate/20130502195415_create_rapidfire_answer_groups.rb +12 -0
- data/db/migrate/20130502195504_create_rapidfire_answers.rb +13 -0
- data/lib/generators/rapidfire/views_generator.rb +23 -0
- data/lib/rapidfire.rb +6 -0
- data/lib/rapidfire/engine.rb +7 -0
- data/lib/rapidfire/version.rb +3 -0
- data/lib/tasks/rapidfire_tasks.rake +4 -0
- metadata +223 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Yuva Kumar
|
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.md
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
# Rapidfire
|
2
|
+
[](https://codeclimate.com/repos/51a70089f3ea000534070811/feed)
|
3
|
+
[](https://travis-ci.org/code-mancers/rapidfire)
|
4
|
+
|
5
|
+
One stop solution for all survey related requirements! Its tad easy!
|
6
|
+
|
7
|
+
This gem supports both **rails 3.2.13+** and **rails4** versions.
|
8
|
+
|
9
|
+
You can see a demo of this gem [here](https://rapidfire.herokuapp.com).
|
10
|
+
And the source code of demo [here](https://github.com/code-mancers/rapidfire-demo).
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'rapidfire'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle install
|
20
|
+
$ bundle exec rake rapidfire:install:migrations
|
21
|
+
$ bundle exec rake db:migrate
|
22
|
+
|
23
|
+
And if you want to customize rapidfire views, you can do
|
24
|
+
|
25
|
+
$ bundle exec rails generate rapidfire:views
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
Add this line to your routes will and you will be good to go!
|
30
|
+
|
31
|
+
mount Rapidfire::Engine => "/rapidfire"
|
32
|
+
|
33
|
+
And point your browser to [http://localhost:3000/rapidfire](http://localhost:3000/rapidfire)
|
34
|
+
|
35
|
+
All rapidfire controllers inherit from your `ApplicationController`. So define 2
|
36
|
+
methods `current_user` and `can_administer?` on your `ApplicationController`
|
37
|
+
|
38
|
+
1. `current_user` : the user who is answering the survey. can be `nil`
|
39
|
+
2. `can_administer?` : a method which determines whether current user can
|
40
|
+
create/update survey questions.
|
41
|
+
|
42
|
+
Typical implementation would be:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
class ApplicationController < ActionController::Base
|
46
|
+
def current_user
|
47
|
+
@current_user ||= User.find(session[:user_id])
|
48
|
+
end
|
49
|
+
|
50
|
+
def can_administer?
|
51
|
+
current_user.try(:admin?)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
If you are using authentication gems like devise, you get `current_user` for free
|
57
|
+
and you don't have to define it.
|
58
|
+
|
59
|
+
### Routes Information
|
60
|
+
Once this gem is mounted on, say at 'rapidfire', it generates several routes
|
61
|
+
You can see them by running `bundle exec rake routes`.
|
62
|
+
|
63
|
+
1. The `root_path` i.e `localhost:3000/rapidfire` always points to list of
|
64
|
+
surveys {they are called question groups}. Admin can manage surveys, and
|
65
|
+
any user {who cannot administer} can see list of surveys.
|
66
|
+
2. Optionally, each survey can by answered by visiting this path:
|
67
|
+
|
68
|
+
```
|
69
|
+
localhost:3000/rapidfire/question_groups/<survey-id>/answer_groups/new
|
70
|
+
```
|
71
|
+
|
72
|
+
You can distribute this url so that survey takers can answer a particular survey
|
73
|
+
of your interest.
|
74
|
+
|
75
|
+
### Survey Results
|
76
|
+
A new api is released which helps in seeing results for each survey. The api is:
|
77
|
+
|
78
|
+
```
|
79
|
+
GET /rapidfire/question_groups/<survey-id>/results
|
80
|
+
```
|
81
|
+
This new api supports two formats: `html` and `json`. The `json` format is supported
|
82
|
+
so that end user can use any javascript based chart solutions and render results
|
83
|
+
in the format they pleased. An example can be seen [here](https://github.com/code-mancers/rapidfire-demo),
|
84
|
+
which uses chart.js to display results.
|
85
|
+
|
86
|
+
Diving into details of `json` format, all the questions can be categorized into
|
87
|
+
one of the two categories:
|
88
|
+
1. **aggregatable**: questions like checkboxes, selects, radio buttons fall into
|
89
|
+
this category.
|
90
|
+
2. **non-aggregatable**: questions like long answers, short answers, date, numeric
|
91
|
+
etc.
|
92
|
+
|
93
|
+
All the aggregatable answers will be returned in the form of hash, and the
|
94
|
+
non-aggregatable answers will be returned in the form of an array. A typical json
|
95
|
+
output will be like this:
|
96
|
+
|
97
|
+
```json
|
98
|
+
[
|
99
|
+
{
|
100
|
+
"question_type": "Rapidfire::Questions::Radio",
|
101
|
+
"question_text": "Who is author of Waiting for godot?",
|
102
|
+
"results": {
|
103
|
+
"Sublime": 1,
|
104
|
+
"Emacs": 1,
|
105
|
+
"Vim": 1
|
106
|
+
}
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"question_type": "Rapidfire::Questions::Checkbox",
|
110
|
+
"question_text": "Best rock band?",
|
111
|
+
"results": {
|
112
|
+
"Led Zeppelin": 2
|
113
|
+
}
|
114
|
+
},
|
115
|
+
{
|
116
|
+
"question_type": "Rapidfire::Questions::Date",
|
117
|
+
"question_text": "When is your birthday?",
|
118
|
+
"results": [
|
119
|
+
"04-02-1983",
|
120
|
+
"01/01/1970"
|
121
|
+
]
|
122
|
+
},
|
123
|
+
{
|
124
|
+
"question_type": "Rapidfire::Questions::Long",
|
125
|
+
"question_text": "If Apple made a android phone what it will be called?",
|
126
|
+
"results": [
|
127
|
+
"Idude",
|
128
|
+
"apdroid"
|
129
|
+
]
|
130
|
+
},
|
131
|
+
{
|
132
|
+
"question_type": "Rapidfire::Questions::Numeric",
|
133
|
+
"question_text": "Answer of life, universe and everything?",
|
134
|
+
"results": [
|
135
|
+
"42",
|
136
|
+
"0"
|
137
|
+
]
|
138
|
+
},
|
139
|
+
{
|
140
|
+
"question_type": "Rapidfire::Questions::Select",
|
141
|
+
"question_text": "Places you want to visit after death",
|
142
|
+
"results": {
|
143
|
+
"Iran": 2
|
144
|
+
}
|
145
|
+
}
|
146
|
+
]
|
147
|
+
```
|
148
|
+
|
149
|
+
## How it works
|
150
|
+
This gem gives you access to create questions in a groups, something similar to
|
151
|
+
survey. Once you have created a group and add questions to it, you can pass
|
152
|
+
around the form url where others can answer your questions.
|
153
|
+
|
154
|
+
The typical flow about how to use this gem is:
|
155
|
+
|
156
|
+
1. Create a question group by giving it a name.
|
157
|
+
2. Once group is created, you can click on the group which takes you to another
|
158
|
+
page where you can manage questions.
|
159
|
+
3. Create a question by clicking on add new, and you will be provided by these
|
160
|
+
options: Each question will have a type
|
161
|
+
- **Checkbox** Create a question which contains multiple checkboxes with the
|
162
|
+
options that you provide in `answer options` field. Note that each option
|
163
|
+
should be on a separate line.
|
164
|
+
- **Date** It takes date as an answer
|
165
|
+
- **Long** It needs a description as answer. Renders a textarea.
|
166
|
+
- **Numeric** It takes a number as an answer
|
167
|
+
- **Radio** It renders set of radio buttons by taking answer options.
|
168
|
+
- **Select** It renders a dropdown by taking answer options.
|
169
|
+
- **Short** It takes a string as an answer. Short answer.
|
170
|
+
|
171
|
+
4. Once the type is filled, you can optionally fill other details like
|
172
|
+
- **Question text** What is the question?
|
173
|
+
- **Answer options** Give options separated by newline for questions of type
|
174
|
+
checkbox, radio buttons or select.
|
175
|
+
- **Answer presence** Should you mandate answering this question?
|
176
|
+
- **min and max length** Checks whether answer if in between min and max length.
|
177
|
+
Ignores if blank.
|
178
|
+
- **greater than and less than** Applicable for numeric question where answer
|
179
|
+
is validated with these values.
|
180
|
+
|
181
|
+
5. Once the questions are populated, you can return to root_path ie by clicking
|
182
|
+
`Question Groups` and share distribute answer url so that others can answer
|
183
|
+
the questions populated.
|
184
|
+
6. Note that answers fail to persist of the criteria that you have provided while
|
185
|
+
creating questions fail.
|
186
|
+
|
187
|
+
|
188
|
+
## TODO
|
189
|
+
1. Add ability to sort questions, so that order is preserved.
|
190
|
+
2. Add multi tenant support.
|
191
|
+
3. Rename question-groups to surveys, and change routes accordingly.
|
192
|
+
|
193
|
+
## Contributing
|
194
|
+
|
195
|
+
1. Fork it
|
196
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
197
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
198
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
199
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
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 = 'Rapidfire'
|
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
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
desc 'Default: run rspec tests.'
|
31
|
+
task :default => :rspec
|
32
|
+
|
33
|
+
desc 'Run rspec unit and integration tests'
|
34
|
+
task :rspec do |t|
|
35
|
+
exec('bundle exec rspec spec')
|
36
|
+
end
|
@@ -0,0 +1,12 @@
|
|
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
|
+
//
|
@@ -0,0 +1,22 @@
|
|
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
|
+
*/
|
13
|
+
|
14
|
+
.horizontal-list {
|
15
|
+
list-style: none;
|
16
|
+
}
|
17
|
+
|
18
|
+
.horizontal-list > li {
|
19
|
+
float: left;
|
20
|
+
display: inline;
|
21
|
+
margin: 0px 5px;
|
22
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rapidfire
|
2
|
+
class AnswerGroupsController < Rapidfire::ApplicationController
|
3
|
+
before_filter :find_question_group!
|
4
|
+
|
5
|
+
def new
|
6
|
+
@answer_group_builder = AnswerGroupBuilder.new(answer_group_params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@answer_group_builder = AnswerGroupBuilder.new(answer_group_params)
|
11
|
+
|
12
|
+
respond_to do |format|
|
13
|
+
if @answer_group_builder.save
|
14
|
+
format.html { redirect_to question_groups_path, notice: 'Survey was successfully created.' }
|
15
|
+
format.json { render json: @answer_group_builder, status: :created, location: @answer_group_builder }
|
16
|
+
else
|
17
|
+
@answer_group_builder.errors.add(:base, "already answered")
|
18
|
+
format.html { render "new" }
|
19
|
+
format.json { render json: @answer_group_builder.errors, status: :unprocessable_entity }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def find_question_group!
|
26
|
+
@question_group = QuestionGroup.find(params[:question_group_id])
|
27
|
+
end
|
28
|
+
|
29
|
+
def answer_group_params
|
30
|
+
answer_params = { params: params[:answer_group] }
|
31
|
+
answer_params.merge(user: current_user, question_group: @question_group, unique_id: request.env["action_dispatch.secret_key_base"] )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Rapidfire
|
2
|
+
class ApplicationController < ::ApplicationController
|
3
|
+
helper_method :can_administer?
|
4
|
+
|
5
|
+
def authenticate_administrator!
|
6
|
+
unless can_administer?
|
7
|
+
raise Rapidfire::AccessDenied.new("cannot administer questions")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Rapidfire
|
2
|
+
class QuestionGroupsController < Rapidfire::ApplicationController
|
3
|
+
before_filter :authenticate_administrator!, except: :index
|
4
|
+
respond_to :html, :js
|
5
|
+
respond_to :json, only: :results
|
6
|
+
|
7
|
+
def index
|
8
|
+
@question_groups = QuestionGroup.all
|
9
|
+
respond_with(@question_groups)
|
10
|
+
end
|
11
|
+
|
12
|
+
def new
|
13
|
+
@question_group = QuestionGroup.new
|
14
|
+
respond_with(@question_group)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create
|
18
|
+
@question_group = QuestionGroup.new(question_group_params)
|
19
|
+
@question_group.save
|
20
|
+
|
21
|
+
respond_with(@question_group, location: rapidfire.question_groups_url)
|
22
|
+
end
|
23
|
+
|
24
|
+
def destroy
|
25
|
+
@question_group = QuestionGroup.find(params[:id])
|
26
|
+
@question_group.destroy
|
27
|
+
|
28
|
+
respond_with(@question_group)
|
29
|
+
end
|
30
|
+
|
31
|
+
def results
|
32
|
+
@question_group = QuestionGroup.find(params[:id])
|
33
|
+
@question_group_results =
|
34
|
+
QuestionGroupResults.new(question_group: @question_group).extract
|
35
|
+
|
36
|
+
respond_with(@question_group_results, root: false)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def question_group_params
|
41
|
+
if Rails::VERSION::MAJOR == 4
|
42
|
+
params.require(:question_group).permit(:name)
|
43
|
+
else
|
44
|
+
params[:question_group]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Rapidfire
|
2
|
+
class QuestionsController < Rapidfire::ApplicationController
|
3
|
+
before_filter :authenticate_administrator!
|
4
|
+
respond_to :html, :js
|
5
|
+
|
6
|
+
before_filter :find_question_group!
|
7
|
+
before_filter :find_question!, :only => [:edit, :update, :destroy]
|
8
|
+
|
9
|
+
def index
|
10
|
+
@questions = @question_group.questions
|
11
|
+
respond_with(@questions)
|
12
|
+
end
|
13
|
+
|
14
|
+
def new
|
15
|
+
@question = QuestionForm.new(:question_group => @question_group)
|
16
|
+
respond_with(@question)
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
form_params = params[:question].merge(:question_group => @question_group)
|
21
|
+
@question = QuestionForm.new(form_params)
|
22
|
+
@question.save
|
23
|
+
|
24
|
+
respond_with(@question, location: index_location)
|
25
|
+
end
|
26
|
+
|
27
|
+
def edit
|
28
|
+
@question = QuestionForm.new(:question => @question)
|
29
|
+
respond_with(@question)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update
|
33
|
+
form_params = params[:question].merge(:question => @question)
|
34
|
+
@question = QuestionForm.new(form_params)
|
35
|
+
@question.save
|
36
|
+
|
37
|
+
respond_with(@question, location: index_location)
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy
|
41
|
+
@question.destroy
|
42
|
+
respond_with(@question, location: index_location)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def find_question_group!
|
47
|
+
@question_group = QuestionGroup.find(params[:question_group_id])
|
48
|
+
end
|
49
|
+
|
50
|
+
def find_question!
|
51
|
+
@question = @question_group.questions.find(params[:id])
|
52
|
+
end
|
53
|
+
|
54
|
+
def index_location
|
55
|
+
rapidfire.question_group_questions_url(@question_group)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|