rapidfire 2.1.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -13
- data/app/controllers/rapidfire/attempts_controller.rb +29 -0
- data/app/controllers/rapidfire/questions_controller.rb +35 -34
- data/app/controllers/rapidfire/surveys_controller.rb +60 -0
- data/app/models/rapidfire/answer.rb +3 -3
- data/app/models/rapidfire/attempt.rb +11 -0
- data/app/models/rapidfire/question.rb +3 -3
- data/app/models/rapidfire/{question_group.rb → survey.rb} +1 -1
- data/app/services/rapidfire/{answer_group_builder.rb → attempt_builder.rb} +12 -12
- data/app/services/rapidfire/base_service.rb +1 -1
- data/app/services/rapidfire/question_form.rb +4 -4
- data/app/services/rapidfire/{question_group_results.rb → survey_results.rb} +3 -3
- data/app/views/rapidfire/{answer_groups → attempts}/new.html.erb +2 -2
- data/app/views/rapidfire/questions/_question.html.erb +2 -2
- data/app/views/rapidfire/questions/edit.html.erb +1 -1
- data/app/views/rapidfire/questions/index.html.erb +1 -1
- data/app/views/rapidfire/questions/new.html.erb +1 -1
- data/app/views/rapidfire/surveys/_form.html.erb +15 -0
- data/app/views/rapidfire/surveys/_survey.html.erb +18 -0
- data/app/views/rapidfire/{question_groups → surveys}/index.html.erb +4 -4
- data/app/views/rapidfire/surveys/new.html.erb +1 -0
- data/app/views/rapidfire/{question_groups → surveys}/results.html.erb +1 -1
- data/config/routes.rb +3 -3
- data/db/migrate/20130502170733_create_rapidfire_question_groups.rb +1 -1
- data/db/migrate/20130502195310_create_rapidfire_questions.rb +2 -2
- data/db/migrate/20130502195415_create_rapidfire_answer_groups.rb +4 -4
- data/db/migrate/20130502195504_create_rapidfire_answers.rb +2 -2
- data/lib/generators/rapidfire/templates/migrations/rename_answer_groups_and_question_groups.rb +9 -0
- data/lib/generators/rapidfire/upgrade_migration_generator.rb +18 -0
- data/lib/generators/rapidfire/views_generator.rb +4 -4
- data/lib/rapidfire/version.rb +1 -1
- data/lib/tasks/rapidfire.rake +10 -0
- data/spec/controllers/rapidfire/attempts_controller_spec.rb +20 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +11 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +61 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +72 -0
- data/spec/dummy/config/environments/test.rb +41 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +8 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +53 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +394 -0
- data/spec/dummy/log/test.log +2380 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/answers_factory.rb +7 -0
- data/spec/factories/attempts_factory.rb +5 -0
- data/spec/factories/questions_factory.rb +30 -0
- data/spec/factories/surveys_factory.rb +5 -0
- data/spec/features/rapidfire/answering_questions_spec.rb +55 -0
- data/spec/features/rapidfire/managing_questions_spec.rb +95 -0
- data/spec/features/rapidfire/managing_surveys_spec.rb +141 -0
- data/spec/models/rapidfire/answer_spec.rb +23 -0
- data/spec/models/rapidfire/attempt_spec.rb +9 -0
- data/spec/models/rapidfire/question_spec.rb +123 -0
- data/spec/models/rapidfire/questions/checkbox_spec.rb +90 -0
- data/spec/models/rapidfire/questions/date_spec.rb +78 -0
- data/spec/models/rapidfire/questions/numeric_spec.rb +114 -0
- data/spec/models/rapidfire/questions/select_spec.rb +90 -0
- data/spec/models/rapidfire/survey_spec.rb +11 -0
- data/spec/serializers/rapidfire/question_result_serializer_spec.rb +44 -0
- data/spec/services/rapidfire/attempt_builder_spec.rb +88 -0
- data/spec/services/rapidfire/question_form_spec.rb +93 -0
- data/spec/services/rapidfire/survey_results_spec.rb +63 -0
- data/spec/spec_helper.rb +68 -0
- data/spec/support/rapidfire/answer_spec_helper.rb +23 -0
- data/spec/support/rapidfire/question_spec_helper.rb +13 -0
- data/spec/tasks/change_delimiter_from_comma_to_srsn_spec.rb +31 -0
- metadata +133 -30
- data/app/controllers/rapidfire/answer_groups_controller.rb +0 -29
- data/app/controllers/rapidfire/question_groups_controller.rb +0 -59
- data/app/models/rapidfire/answer_group.rb +0 -11
- data/app/views/rapidfire/question_groups/_form.html.erb +0 -15
- data/app/views/rapidfire/question_groups/_question_group.html.erb +0 -18
- data/app/views/rapidfire/question_groups/new.html.erb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27b98c4be749e5dd26dc5021426543880ad344c8
|
4
|
+
data.tar.gz: 70dd426049dce2c447d567ccf25b1206201e32ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 394966bd048f4932b06c9a7a222f88a1754a85275591c2ab38397bea7d318b1a9ff9bf27ad78f2924592dec81c194fb57db34df01fa235ec2122b1055cba6787
|
7
|
+
data.tar.gz: 95c9d6b0eb5c44d854699fb3b3a64d0f44ab81935f5b2c8916fa4773220e6bfc3155e9cb7f1be29e80178d341d8453874d69c75b6d6b0330f3018e2376e8a992
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Rapidfire
|
2
|
-
[![Code Climate](https://codeclimate.com/
|
2
|
+
[![Code Climate](https://codeclimate.com/github/code-mancers/rapidfire/badges/gpa.svg)](https://codeclimate.com/github/code-mancers/rapidfire)
|
3
3
|
[![Build Status](https://travis-ci.org/code-mancers/rapidfire.png?branch=master)](https://travis-ci.org/code-mancers/rapidfire)
|
4
4
|
|
5
5
|
One stop solution for all survey related requirements! Its tad easy!
|
6
6
|
|
7
|
-
This gem supports
|
7
|
+
This gem supports **rails 3.2.13+**, **rails4** and **rails5** versions.
|
8
8
|
|
9
9
|
You can see a demo of this gem [here](https://rapidfire.herokuapp.com).
|
10
10
|
And the source code of demo [here](https://github.com/code-mancers/rapidfire-demo).
|
@@ -12,13 +12,17 @@ And the source code of demo [here](https://github.com/code-mancers/rapidfire-dem
|
|
12
12
|
## Installation
|
13
13
|
Add this line to your application's Gemfile:
|
14
14
|
|
15
|
+
```rb
|
15
16
|
gem 'rapidfire'
|
17
|
+
```
|
16
18
|
|
17
19
|
And then execute:
|
18
20
|
|
21
|
+
```shell
|
19
22
|
$ bundle install
|
20
23
|
$ bundle exec rake rapidfire:install:migrations
|
21
24
|
$ bundle exec rake db:migrate
|
25
|
+
```
|
22
26
|
|
23
27
|
And if you want to customize rapidfire views, you can do
|
24
28
|
|
@@ -28,7 +32,9 @@ And if you want to customize rapidfire views, you can do
|
|
28
32
|
|
29
33
|
Add this line to your routes will and you will be good to go!
|
30
34
|
|
35
|
+
```rb
|
31
36
|
mount Rapidfire::Engine => "/rapidfire"
|
37
|
+
```
|
32
38
|
|
33
39
|
And point your browser to [http://localhost:3000/rapidfire](http://localhost:3000/rapidfire)
|
34
40
|
|
@@ -41,7 +47,7 @@ methods `current_user` and `can_administer?` on your `ApplicationController`
|
|
41
47
|
|
42
48
|
Typical implementation would be:
|
43
49
|
|
44
|
-
```
|
50
|
+
```rb
|
45
51
|
class ApplicationController < ActionController::Base
|
46
52
|
def current_user
|
47
53
|
@current_user ||= User.find(session[:user_id])
|
@@ -66,7 +72,7 @@ You can see them by running `bundle exec rake routes`.
|
|
66
72
|
2. Optionally, each survey can by answered by visiting this path:
|
67
73
|
|
68
74
|
```
|
69
|
-
localhost:3000/rapidfire/
|
75
|
+
localhost:3000/rapidfire/surveys/<survey-id>/answer_groups/new
|
70
76
|
```
|
71
77
|
|
72
78
|
You can distribute this url so that survey takers can answer a particular survey
|
@@ -76,7 +82,7 @@ You can see them by running `bundle exec rake routes`.
|
|
76
82
|
A new api is released which helps in seeing results for each survey. The api is:
|
77
83
|
|
78
84
|
```
|
79
|
-
GET /rapidfire/
|
85
|
+
GET /rapidfire/surveys/<survey-id>/results
|
80
86
|
```
|
81
87
|
This new api supports two formats: `html` and `json`. The `json` format is supported
|
82
88
|
so that end user can use any javascript based chart solutions and render results
|
@@ -179,13 +185,22 @@ The typical flow about how to use this gem is:
|
|
179
185
|
is validated with these values.
|
180
186
|
|
181
187
|
5. Once the questions are populated, you can return to root_path ie by clicking
|
182
|
-
`
|
188
|
+
`Surveys` and share distribute answer url so that others can answer
|
183
189
|
the questions populated.
|
184
190
|
6. Note that answers fail to persist of the criteria that you have provided while
|
185
191
|
creating questions fail.
|
186
192
|
|
187
193
|
|
188
194
|
## Notes on upgrading
|
195
|
+
|
196
|
+
##### Upgrading from 2.1.0 to 3.0.0
|
197
|
+
|
198
|
+
If you are upgrading you need to rename your `rapidfire_question_groups` to `rapidfire_surveys` and `rapidfire_answer_groups` to `rapidfire_attempts`. Run the given task to do that for you.
|
199
|
+
|
200
|
+
```shell
|
201
|
+
$ rake rapidfire:upgrade:migrations:from210to300
|
202
|
+
```
|
203
|
+
|
189
204
|
##### Upgrading from 1.2.0 to 2.0.0
|
190
205
|
|
191
206
|
The default delimiter which is used to store options for questions like select
|
@@ -199,7 +214,8 @@ to make existing questions or stored answers to use new delimiter.
|
|
199
214
|
|
200
215
|
NOTE: Please take database backup before running this rake task.
|
201
216
|
|
202
|
-
```
|
217
|
+
```rb
|
218
|
+
bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn
|
203
219
|
bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn
|
204
220
|
```
|
205
221
|
|
@@ -209,19 +225,18 @@ as delimiter, then please use this initializer, but be warned that in future
|
|
209
225
|
delimiter will be hardcoded to `\r\n`:
|
210
226
|
|
211
227
|
|
212
|
-
```
|
213
|
-
# /<path-to-app>/config/initializers/rapidfire.rb
|
228
|
+
```rb
|
229
|
+
# /<path-to-app>/config/initializers/rapidfire.rb
|
214
230
|
|
215
|
-
Rapidfire.config do |config|
|
216
|
-
|
217
|
-
end
|
231
|
+
Rapidfire.config do |config|
|
232
|
+
config.answers_delimiter = ','
|
233
|
+
end
|
218
234
|
```
|
219
235
|
|
220
236
|
|
221
237
|
## TODO
|
222
238
|
1. Add ability to sort questions, so that order is preserved.
|
223
239
|
2. Add multi tenant support.
|
224
|
-
3. Rename question-groups to surveys, and change routes accordingly.
|
225
240
|
|
226
241
|
## Contributing
|
227
242
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rapidfire
|
2
|
+
class AttemptsController < Rapidfire::ApplicationController
|
3
|
+
before_filter :find_survey!
|
4
|
+
|
5
|
+
def new
|
6
|
+
@attempt_builder = AttemptBuilder.new(attempt_params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@attempt_builder = AttemptBuilder.new(attempt_params)
|
11
|
+
|
12
|
+
if @attempt_builder.save
|
13
|
+
redirect_to surveys_path
|
14
|
+
else
|
15
|
+
render :new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def find_survey!
|
21
|
+
@survey = Survey.find(params[:survey_id])
|
22
|
+
end
|
23
|
+
|
24
|
+
def attempt_params
|
25
|
+
answer_params = { params: (params[:attempt] || {}) }
|
26
|
+
answer_params.merge(user: current_user, survey: @survey)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -2,33 +2,21 @@ module Rapidfire
|
|
2
2
|
class QuestionsController < Rapidfire::ApplicationController
|
3
3
|
before_filter :authenticate_administrator!
|
4
4
|
|
5
|
-
before_filter :
|
5
|
+
before_filter :find_survey!
|
6
6
|
before_filter :find_question!, :only => [:edit, :update, :destroy]
|
7
7
|
|
8
8
|
def index
|
9
|
-
@questions = @
|
9
|
+
@questions = @survey.questions
|
10
10
|
end
|
11
11
|
|
12
12
|
def new
|
13
|
-
@question_form = QuestionForm.new(:
|
13
|
+
@question_form = QuestionForm.new(:survey => @survey)
|
14
14
|
end
|
15
15
|
|
16
16
|
def create
|
17
|
-
form_params =
|
18
|
-
@question_form = QuestionForm.new(form_params)
|
19
|
-
@question_form.save
|
17
|
+
form_params = question_params.merge(:survey => @survey)
|
20
18
|
|
21
|
-
|
22
|
-
respond_to do |format|
|
23
|
-
format.html { redirect_to index_location }
|
24
|
-
format.js
|
25
|
-
end
|
26
|
-
else
|
27
|
-
respond_to do |format|
|
28
|
-
format.html { render :new }
|
29
|
-
format.js
|
30
|
-
end
|
31
|
-
end
|
19
|
+
save_and_redirect(form_params, :new)
|
32
20
|
end
|
33
21
|
|
34
22
|
def edit
|
@@ -36,8 +24,23 @@ module Rapidfire
|
|
36
24
|
end
|
37
25
|
|
38
26
|
def update
|
39
|
-
form_params =
|
40
|
-
|
27
|
+
form_params = question_params.merge(:question => @question)
|
28
|
+
|
29
|
+
save_and_redirect(form_params, :edit)
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroy
|
33
|
+
@question.destroy
|
34
|
+
respond_to do |format|
|
35
|
+
format.html { redirect_to index_location }
|
36
|
+
format.js
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def save_and_redirect(params, on_error_key)
|
43
|
+
@question_form = QuestionForm.new(params)
|
41
44
|
@question_form.save
|
42
45
|
|
43
46
|
if @question_form.errors.empty?
|
@@ -47,32 +50,30 @@ module Rapidfire
|
|
47
50
|
end
|
48
51
|
else
|
49
52
|
respond_to do |format|
|
50
|
-
format.html { render
|
53
|
+
format.html { render on_error_key.to_sym }
|
51
54
|
format.js
|
52
55
|
end
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
56
|
-
def
|
57
|
-
@
|
58
|
-
respond_to do |format|
|
59
|
-
format.html { redirect_to index_location }
|
60
|
-
format.js
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def find_question_group!
|
67
|
-
@question_group = QuestionGroup.find(params[:question_group_id])
|
59
|
+
def find_survey!
|
60
|
+
@survey = Survey.find(params[:survey_id])
|
68
61
|
end
|
69
62
|
|
70
63
|
def find_question!
|
71
|
-
@question = @
|
64
|
+
@question = @survey.questions.find(params[:id])
|
72
65
|
end
|
73
66
|
|
74
67
|
def index_location
|
75
|
-
rapidfire.
|
68
|
+
rapidfire.survey_questions_url(@survey)
|
69
|
+
end
|
70
|
+
|
71
|
+
def question_params
|
72
|
+
if Rails::VERSION::MAJOR == 4 || Rails::VERSION::MAJOR == 5
|
73
|
+
params.require(:question).permit!
|
74
|
+
else
|
75
|
+
params[:question]
|
76
|
+
end
|
76
77
|
end
|
77
78
|
end
|
78
79
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Rapidfire
|
2
|
+
class SurveysController < Rapidfire::ApplicationController
|
3
|
+
before_filter :authenticate_administrator!, except: :index
|
4
|
+
|
5
|
+
def index
|
6
|
+
@surveys = Survey.all
|
7
|
+
end
|
8
|
+
|
9
|
+
def new
|
10
|
+
@survey = Survey.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
@survey = Survey.new(survey_params)
|
15
|
+
if @survey.save
|
16
|
+
respond_to do |format|
|
17
|
+
format.html { redirect_to surveys_path }
|
18
|
+
format.js
|
19
|
+
end
|
20
|
+
else
|
21
|
+
respond_to do |format|
|
22
|
+
format.html { render :new }
|
23
|
+
format.js
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy
|
29
|
+
@survey = Survey.find(params[:id])
|
30
|
+
@survey.destroy
|
31
|
+
|
32
|
+
respond_to do |format|
|
33
|
+
format.html { redirect_to surveys_path }
|
34
|
+
format.js
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def results
|
39
|
+
@survey = Survey.find(params[:id])
|
40
|
+
@survey_results =
|
41
|
+
SurveyResults.new(survey: @survey).extract
|
42
|
+
|
43
|
+
respond_to do |format|
|
44
|
+
format.json { render json: @survey_results, root: false }
|
45
|
+
format.html
|
46
|
+
format.js
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def survey_params
|
53
|
+
if Rails::VERSION::MAJOR >= 4
|
54
|
+
params.require(:survey).permit(:name)
|
55
|
+
else
|
56
|
+
params[:survey]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module Rapidfire
|
2
2
|
class Answer < ActiveRecord::Base
|
3
3
|
belongs_to :question
|
4
|
-
belongs_to :
|
4
|
+
belongs_to :attempt, inverse_of: :answers
|
5
5
|
|
6
|
-
validates :question, :
|
6
|
+
validates :question, :attempt, presence: true
|
7
7
|
validate :verify_answer_text, :if => "question.present?"
|
8
8
|
|
9
9
|
if Rails::VERSION::MAJOR == 3
|
10
|
-
attr_accessible :question_id, :
|
10
|
+
attr_accessible :question_id, :attempt, :answer_text
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module Rapidfire
|
2
2
|
class Question < ActiveRecord::Base
|
3
|
-
belongs_to :
|
3
|
+
belongs_to :survey, :inverse_of => :questions
|
4
4
|
has_many :answers
|
5
5
|
|
6
6
|
default_scope { order(:position) }
|
7
7
|
|
8
|
-
validates :
|
8
|
+
validates :survey, :question_text, :presence => true
|
9
9
|
serialize :validation_rules
|
10
10
|
|
11
11
|
if Rails::VERSION::MAJOR == 3
|
12
|
-
attr_accessible :
|
12
|
+
attr_accessible :survey, :question_text, :validation_rules, :answer_options
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.inherited(child)
|
@@ -1,19 +1,19 @@
|
|
1
1
|
module Rapidfire
|
2
|
-
class
|
3
|
-
attr_accessor :user, :
|
2
|
+
class AttemptBuilder < Rapidfire::BaseService
|
3
|
+
attr_accessor :user, :survey, :questions, :answers, :params
|
4
4
|
|
5
5
|
def initialize(params = {})
|
6
6
|
super(params)
|
7
|
-
|
7
|
+
build_attempt
|
8
8
|
end
|
9
9
|
|
10
10
|
def to_model
|
11
|
-
@
|
11
|
+
@attempt
|
12
12
|
end
|
13
13
|
|
14
14
|
def save!(options = {})
|
15
15
|
params.each do |question_id, answer_attributes|
|
16
|
-
if answer = @
|
16
|
+
if answer = @attempt.answers.find { |a| a.question_id.to_s == question_id.to_s }
|
17
17
|
text = answer_attributes[:answer_text]
|
18
18
|
|
19
19
|
# in case of checkboxes, values are submitted as an array of
|
@@ -29,24 +29,24 @@ module Rapidfire
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
@
|
32
|
+
@attempt.save!(options)
|
33
33
|
end
|
34
34
|
|
35
35
|
def save(options = {})
|
36
36
|
save!(options)
|
37
37
|
rescue ActiveRecord::ActiveRecordError => e
|
38
38
|
# repopulate answers here in case of failure as they are not getting updated
|
39
|
-
@answers = @
|
40
|
-
@
|
39
|
+
@answers = @survey.questions.collect do |question|
|
40
|
+
@attempt.answers.find { |a| a.question_id == question.id }
|
41
41
|
end
|
42
42
|
false
|
43
43
|
end
|
44
44
|
|
45
45
|
private
|
46
|
-
def
|
47
|
-
@
|
48
|
-
@answers = @
|
49
|
-
@
|
46
|
+
def build_attempt
|
47
|
+
@attempt = Attempt.new(user: user, survey: survey)
|
48
|
+
@answers = @survey.questions.collect do |question|
|
49
|
+
@attempt.answers.build(question_id: question.id)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|