ask 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +14 -0
- data/Rakefile +1 -1
- data/app/assets/javascripts/ask.js.coffee +7 -3
- data/app/assets/stylesheets/ask.css.scss +1 -1
- data/app/models/answer.rb +20 -2
- data/app/models/question.rb +6 -1
- data/app/models/upload_question.rb +7 -0
- data/app/uploaders/uploaded_file_uploader.rb +55 -0
- data/app/views/answerer/_answers.html.erb +22 -0
- data/app/views/answerer/_form.html.erb +34 -0
- data/app/views/asker/_choice_fields.html.erb +7 -0
- data/app/views/asker/_choices.html.erb +27 -0
- data/app/views/asker/_form.html.erb +7 -0
- data/app/views/asker/_form_preview.html.erb +11 -0
- data/app/views/asker/_question_fields.html.erb +46 -0
- data/app/views/questions/_checklist_question.html.erb +5 -0
- data/app/views/questions/_choose_one_question.html.erb +10 -0
- data/app/views/questions/_essay_question.html.erb +1 -0
- data/app/views/questions/_form_section.erb +4 -0
- data/app/views/questions/_label.html.erb +4 -0
- data/app/views/questions/_text_question.html.erb +1 -0
- data/app/views/questions/_upload_question.html.erb +6 -0
- data/db/migrate/20130202010401_add_upload_field_to_answers.rb +5 -0
- data/lib/ask.rb +10 -0
- data/lib/ask/acts_as_answerer.rb +4 -3
- data/lib/ask/configuration.rb +9 -0
- data/lib/ask/version.rb +1 -1
- metadata +50 -109
- data/app/views/answerer/_answers.html.haml +0 -11
- data/app/views/answerer/_form.html.haml +0 -37
- data/app/views/asker/_choice_fields.html.haml +0 -6
- data/app/views/asker/_choices.html.haml +0 -17
- data/app/views/asker/_form.html.haml +0 -5
- data/app/views/asker/_form_preview.html.haml +0 -35
- data/app/views/asker/_question_fields.html.haml +0 -33
- data/test/ask_test.rb +0 -7
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/assets/javascripts/application.js +0 -9
- data/test/dummy/app/assets/stylesheets/application.css +0 -7
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -45
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -30
- data/test/dummy/config/environments/production.rb +0 -60
- data/test/dummy/config/environments/test.rb +0 -42
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -10
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -7
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -58
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -26
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +0 -6
- data/test/fixtures/answers.yml +0 -13
- data/test/fixtures/choices.yml +0 -9
- data/test/fixtures/questions.yml +0 -17
- data/test/fixtures/submissions.yml +0 -9
- data/test/functional/answers_controller_test.rb +0 -49
- data/test/functional/choices_controller_test.rb +0 -49
- data/test/functional/questions_controller_test.rb +0 -49
- data/test/integration/navigation_test.rb +0 -10
- data/test/test_helper.rb +0 -10
- data/test/unit/answer_test.rb +0 -7
- data/test/unit/choice_test.rb +0 -7
- data/test/unit/helpers/answers_helper_test.rb +0 -4
- data/test/unit/helpers/choices_helper_test.rb +0 -4
- data/test/unit/helpers/questions_helper_test.rb +0 -4
- data/test/unit/question_test.rb +0 -7
data/README.markdown
CHANGED
@@ -7,6 +7,10 @@ Requirements
|
|
7
7
|
- Rails 3.1 or higher
|
8
8
|
- jQuery
|
9
9
|
- jQuery UI
|
10
|
+
- Uses Carrierwave for uploads
|
11
|
+
|
12
|
+
More information will be on the [wiki](https://github.com/biola/ask/wiki).
|
13
|
+
|
10
14
|
|
11
15
|
Installation
|
12
16
|
------------
|
@@ -76,6 +80,16 @@ Finally you'll need to define an `asker` method on your answerer model, like so:
|
|
76
80
|
end
|
77
81
|
end
|
78
82
|
|
83
|
+
|
84
|
+
Configuration
|
85
|
+
-------------
|
86
|
+
If you want to changed the default whitelisted file types for upload questions, just drop this into an initializer file.
|
87
|
+
|
88
|
+
Ask.configure do |config|
|
89
|
+
@upload_whitelist = %w(jpg jpeg gif png doc docx txt pdf xls xlsx zip)
|
90
|
+
end
|
91
|
+
|
92
|
+
|
79
93
|
License
|
80
94
|
-------
|
81
95
|
MIT License
|
data/Rakefile
CHANGED
@@ -20,7 +20,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
20
20
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
21
|
end
|
22
22
|
|
23
|
-
APP_RAKEFILE = File.expand_path("../
|
23
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
24
|
load 'rails/tasks/engine.rake'
|
25
25
|
|
26
26
|
|
@@ -34,9 +34,10 @@ jQuery ->
|
|
34
34
|
question.find('.required-option').hide()
|
35
35
|
|
36
36
|
# Update preview type whenever the user changes the type of this question
|
37
|
+
$('form').on "change", ".select-question-type select", ->
|
38
|
+
updateChoiceVisibility $(this)
|
39
|
+
|
37
40
|
bindTypeChange = (select) ->
|
38
|
-
select.live "change", ->
|
39
|
-
updateChoiceVisibility $(this)
|
40
41
|
|
41
42
|
# Update once when the DOM first loads
|
42
43
|
selects = $(".select-question-type select")
|
@@ -82,6 +83,9 @@ jQuery ->
|
|
82
83
|
when "EssayQuestion"
|
83
84
|
preview_section.append(q_label).append("<textarea></textarea>")
|
84
85
|
preview_section.append(q_help_text) if q_help_text
|
86
|
+
when "UploadQuestion"
|
87
|
+
preview_section.append(q_label).append("<input type='file'>")
|
88
|
+
preview_section.append(q_help_text) if q_help_text
|
85
89
|
when "ChooseOneQuestion"
|
86
90
|
preview_section.append(q_label)
|
87
91
|
preview_section.append(q_help_text) if q_help_text
|
@@ -122,7 +126,7 @@ jQuery ->
|
|
122
126
|
$('fieldset.question').each ->
|
123
127
|
createQuestionPreview $(this)
|
124
128
|
|
125
|
-
$('a.edit-question-link
|
129
|
+
$('form').on "click", "a.edit-question-link", (e) ->
|
126
130
|
toggleEditMode($(this).closest('fieldset.question'))
|
127
131
|
e.preventDefault()
|
128
132
|
|
@@ -17,7 +17,7 @@
|
|
17
17
|
&.preview { // hide edit fields when in preview mode
|
18
18
|
.edit-question-fields { display: none; }
|
19
19
|
input[type="checkbox"], input[type="radio"] { margin: 0 8px 4px; }
|
20
|
-
label.preview-question-name { font-weight: bold; }
|
20
|
+
label.preview-question-name { font-weight: bold; display: block; }
|
21
21
|
h3 { margin-bottom: 0; }
|
22
22
|
hr { margin-bottom: 0; border-top: 1px solid #EEE; border-bottom: none; }
|
23
23
|
.help-block { color: #595959; }
|
data/app/models/answer.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Answer < ActiveRecord::Base
|
2
2
|
|
3
|
-
attr_accessible :question_id, :answer, :choice_id
|
3
|
+
attr_accessible :question_id, :answer, :choice_id, :uploaded_file, :uploaded_file_cache
|
4
4
|
|
5
5
|
belongs_to :answerer, :polymorphic => true
|
6
6
|
belongs_to :question
|
@@ -8,12 +8,30 @@ class Answer < ActiveRecord::Base
|
|
8
8
|
|
9
9
|
validates_presence_of :question_id
|
10
10
|
|
11
|
+
mount_uploader :uploaded_file, UploadedFileUploader
|
12
|
+
|
11
13
|
default_scope joins(:question).order('questions.position')
|
12
14
|
scope :for_answerer, lambda{|answerer| where(:answerer_type => answerer.class.to_s, :answerer_id => answerer.id)}
|
13
15
|
scope :for_question, lambda{|question| where(:question_id => question.id)}
|
14
16
|
|
15
17
|
def to_s
|
16
|
-
|
18
|
+
if question.supports_uploads?
|
19
|
+
self.uploaded_file.url
|
20
|
+
else
|
21
|
+
self.answer.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# This method is used to see if the answer fails to meat "required" status if the question is required.
|
26
|
+
# should return true on fail and nil/false on success.
|
27
|
+
def fails_required?
|
28
|
+
if question.required
|
29
|
+
if question.supports_uploads?
|
30
|
+
uploaded_file.blank?
|
31
|
+
else
|
32
|
+
answer.blank?
|
33
|
+
end
|
34
|
+
end
|
17
35
|
end
|
18
36
|
|
19
37
|
end
|
data/app/models/question.rb
CHANGED
@@ -2,7 +2,7 @@ class Question < ActiveRecord::Base
|
|
2
2
|
|
3
3
|
require 'acts_as_list'
|
4
4
|
|
5
|
-
TYPES = ['TextQuestion', 'EssayQuestion', 'ChooseOneQuestion', 'ChecklistQuestion', 'FormSection']
|
5
|
+
TYPES = ['TextQuestion', 'EssayQuestion', 'ChooseOneQuestion', 'ChecklistQuestion', 'UploadQuestion', 'FormSection']
|
6
6
|
|
7
7
|
belongs_to :asker, :polymorphic => true
|
8
8
|
has_many :choices, :dependent => :destroy
|
@@ -25,6 +25,7 @@ class Question < ActiveRecord::Base
|
|
25
25
|
default
|
26
26
|
end
|
27
27
|
|
28
|
+
# This just means it doesn't expect an answer, such as a form_section question
|
28
29
|
def rhetorical?
|
29
30
|
false
|
30
31
|
end
|
@@ -42,4 +43,8 @@ class Question < ActiveRecord::Base
|
|
42
43
|
false
|
43
44
|
end
|
44
45
|
|
46
|
+
def supports_uploads?
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
45
50
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class UploadedFileUploader < CarrierWave::Uploader::Base
|
4
|
+
|
5
|
+
# Include RMagick or MiniMagick support:
|
6
|
+
# include CarrierWave::RMagick
|
7
|
+
# include CarrierWave::MiniMagick
|
8
|
+
|
9
|
+
# Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
|
10
|
+
# include Sprockets::Helpers::RailsHelper
|
11
|
+
# include Sprockets::Helpers::IsolatedHelper
|
12
|
+
|
13
|
+
# Choose what kind of storage to use for this uploader:
|
14
|
+
storage :file
|
15
|
+
# storage :fog
|
16
|
+
|
17
|
+
# Override the directory where uploaded files will be stored.
|
18
|
+
# This is a sensible default for uploaders that are meant to be mounted:
|
19
|
+
def store_dir
|
20
|
+
"file_uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Provide a default URL as a default if there hasn't been a file uploaded:
|
24
|
+
# def default_url
|
25
|
+
# # For Rails 3.1+ asset pipeline compatibility:
|
26
|
+
# # asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
27
|
+
#
|
28
|
+
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
29
|
+
# end
|
30
|
+
|
31
|
+
# Process files as they are uploaded:
|
32
|
+
# process :scale => [200, 300]
|
33
|
+
#
|
34
|
+
# def scale(width, height)
|
35
|
+
# # do something
|
36
|
+
# end
|
37
|
+
|
38
|
+
# Create different versions of your uploaded files:
|
39
|
+
# version :thumb do
|
40
|
+
# process :scale => [50, 50]
|
41
|
+
# end
|
42
|
+
|
43
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
44
|
+
# For images you might use something like this:
|
45
|
+
def extension_white_list
|
46
|
+
Ask.config.upload_whitelist
|
47
|
+
end
|
48
|
+
|
49
|
+
# Override the filename of the uploaded files:
|
50
|
+
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
51
|
+
# def filename
|
52
|
+
# "something.jpg" if original_filename
|
53
|
+
# end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<% raise 'You must pass in an "answerer" to use this partial' unless defined?(answerer) %>
|
2
|
+
|
3
|
+
<% answerer.questions_by_section.each do |section, questions| %>
|
4
|
+
<% unless section.nil? %>
|
5
|
+
<h3><%= section.name %></h3>
|
6
|
+
<p><%= section.instructions %></p>
|
7
|
+
<% end %>
|
8
|
+
<dl>
|
9
|
+
<% questions.each do |question| %>
|
10
|
+
<dt><%= question.name %></dt>
|
11
|
+
<% answerer.answers_to(question).each do |answer| %>
|
12
|
+
<dd>
|
13
|
+
<% if answer.is_a?(Answer) && answer.question.supports_uploads? && !answer.uploaded_file.blank? %>
|
14
|
+
<%= link_to answer.to_s, answer.uploaded_file.url, target: "_blank" %>
|
15
|
+
<% else %>
|
16
|
+
<%= simple_format(answer.to_s) %>
|
17
|
+
<% end %>
|
18
|
+
</dd>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
</dl>
|
22
|
+
<% end %>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% @prev_question_id == nil %>
|
2
|
+
<%= f.fields_for(:answers) do |answer| %>
|
3
|
+
|
4
|
+
<% question = answer.object.question %>
|
5
|
+
<%= answer.hidden_field(:question_id, value: question.id) %>
|
6
|
+
|
7
|
+
<% if question.rhetorical? # aka, it does not need to be answered %>
|
8
|
+
<% case(question.type.to_sym) %>
|
9
|
+
<% when :FormSection %>
|
10
|
+
<%= render 'questions/form_section', answer: answer, question: question %>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<% else %>
|
14
|
+
<% if question.supports_multiple_answers? && (@prev_question_id == question.id) %>
|
15
|
+
<% # Don't redisplay the label again for each checklist choice, just display it the first time %>
|
16
|
+
<% else %>
|
17
|
+
<%= render 'questions/label', answer: answer, question: question %>
|
18
|
+
<% @prev_question_id = question.id %>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<% case(question.type.to_sym) %>
|
22
|
+
<% when :TextQuestion %>
|
23
|
+
<%= render 'questions/text_question', answer: answer, question: question %>
|
24
|
+
<% when :EssayQuestion %>
|
25
|
+
<%= render 'questions/essay_question', answer: answer, question: question %>
|
26
|
+
<% when :UploadQuestion %>
|
27
|
+
<%= render 'questions/upload_question', answer: answer, question: question %>
|
28
|
+
<% when :ChooseOneQuestion %>
|
29
|
+
<%= render 'questions/choose_one_question', answer: answer, question: question %>
|
30
|
+
<% when :ChecklistQuestion %>
|
31
|
+
<%= render 'questions/checklist_question', answer: answer, question: question %>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<fieldset class = "choice">
|
2
|
+
<input type = "radio" disabled = "disabled" class = "radio-preview"></input>
|
3
|
+
<input type = "checkbox" disabled = "disabled" class = "checkbox-preview"></input>
|
4
|
+
<%= f.text_field :name, :placeholder=>'Choice' %>
|
5
|
+
<%= f.hidden_field :_destroy %>
|
6
|
+
<%= link_to "remove", '#', class: "remove_fields" %>
|
7
|
+
</fieldset>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<div class = "question-type TextQuestion">
|
2
|
+
<input type = "text" disabled = "disabled" name = "undefined" value = "Their answer" class = "askwidget-disabledpreview"></input>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<div class = "question-type EssayQuestion start-hidden">
|
6
|
+
<textarea disabled = "disabled" name = "undefined" type = "text" value = "Their answer" class = "askwidget-disabledpreview"></textarea>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class = "question-type UploadQuestion">
|
10
|
+
<input type = "file" disabled = "disabled" name = "undefined" value = "Their answer" class = "askwidget-disabledpreview"></input>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div class = "question-type ChooseOneQuestion ChecklistQuestion start-hidden">
|
14
|
+
<%= f.fields_for(:choices) do |choice| %>
|
15
|
+
<%= render 'asker/choice_fields', f: choice %>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<%= link_to_add_fields "Add Choice", f, :choices %>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div class = "question-type FormSection start-hidden">
|
22
|
+
<h4> Name of section </h4>
|
23
|
+
<p>
|
24
|
+
This will provide a divider between form sections
|
25
|
+
</p>
|
26
|
+
</div>
|
27
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% raise 'You must pass in a "answerer" to use this partial' unless defined?(answerer) %>
|
2
|
+
|
3
|
+
<%= form_for answerer, url: "#", html: {class: "form-horizontal form-preview"} do |f| %>
|
4
|
+
<fieldset>
|
5
|
+
<% # This partial is loaded from the ask gem %>
|
6
|
+
<%= render(partial: 'answerer/form', locals: { f: f }) %>
|
7
|
+
</fieldset>
|
8
|
+
<div class="form-actions">
|
9
|
+
<%= f.submit 'Submit Form', class: "btn btn-primary disabled", disabled: :disabled %>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<fieldset class = "question preview">
|
2
|
+
<div class = "question-action-links">
|
3
|
+
<%= link_to 'Edit', '#', class: 'edit-question-link' %>
|
4
|
+
|
|
5
|
+
<%= f.hidden_field :_destroy %>
|
6
|
+
<%= link_to "Remove", '#', class: "remove_fields" %>
|
7
|
+
</div>
|
8
|
+
<div class = "hidden position-wrapper">
|
9
|
+
<%= f.hidden_field(:position) %>
|
10
|
+
</div>
|
11
|
+
<div class = "edit-question-fields">
|
12
|
+
<table class = "question-details">
|
13
|
+
<tbody>
|
14
|
+
<tr>
|
15
|
+
<th>
|
16
|
+
<span class = "askwidget-fieldlabel"><%= f.label(:name) %></span>
|
17
|
+
</th>
|
18
|
+
<td><%= f.text_field :name, class: 'askwidget-inputfield' %></td>
|
19
|
+
</tr>
|
20
|
+
<tr>
|
21
|
+
<th>
|
22
|
+
<span class = "askwidget-fieldlabel"><%= f.label(:instructions, 'Help Text') %></span>
|
23
|
+
</th>
|
24
|
+
<td><%= f.text_field :instructions, class: 'askwidget-inputfield' %></td>
|
25
|
+
</tr>
|
26
|
+
<tr class = "select-question-type">
|
27
|
+
<th>
|
28
|
+
<span class = "askwidget-fieldlabel"><%= f.label(:type) %></span>
|
29
|
+
</th>
|
30
|
+
<td><%= f.collection_select :type, Question::TYPES, :to_s, :titleize, class: 'askwidget-inputfield' %></td>
|
31
|
+
</table>
|
32
|
+
|
33
|
+
|
34
|
+
<div class = "edit-question-choices">
|
35
|
+
<%= render 'asker/choices', f: f %>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<div class = "askwidget-buttons">
|
39
|
+
<%= link_to "Done", "#", class: 'edit-question-link btn' %>
|
40
|
+
<div class = "required-option">
|
41
|
+
<%= f.check_box :required, class: 'askwidget-inputfield' %>
|
42
|
+
<span class = "askwidget-fieldlabel"><%= f.label(:required, "Make this a required question") %></span>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
</fieldset>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% if question.choices.count > 5 %>
|
2
|
+
<dd><%= answer.collection_select(:answer, question.choice_names, :to_s, :to_s, :include_blank=>!question.required)%></dd>
|
3
|
+
<% else %>
|
4
|
+
<% question.choices.each do |choice| %>
|
5
|
+
<dd>
|
6
|
+
<%=answer.radio_button(:answer, choice.name) %>
|
7
|
+
<%=answer.label(:answer, choice.name, :value=>choice.name) %>
|
8
|
+
</dd>
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<dd><%= answer.text_area(:answer) %></dd>
|
@@ -0,0 +1 @@
|
|
1
|
+
<dd><%= answer.text_field(:answer) %></dd>
|
data/lib/ask.rb
CHANGED
@@ -1,6 +1,16 @@
|
|
1
1
|
require "ask/engine"
|
2
2
|
require "ask/acts_as_asker"
|
3
3
|
require "ask/acts_as_answerer"
|
4
|
+
require "carrierwave"
|
4
5
|
|
5
6
|
module Ask
|
7
|
+
require 'ask/configuration'
|
8
|
+
|
9
|
+
def self.configure
|
10
|
+
yield config
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.config
|
14
|
+
@config ||= Configuration.new
|
15
|
+
end
|
6
16
|
end
|
data/lib/ask/acts_as_answerer.rb
CHANGED
@@ -76,11 +76,11 @@ module Ask
|
|
76
76
|
|
77
77
|
# Set the correct order and make sure we have all the questions
|
78
78
|
all_questions.each do |q|
|
79
|
-
qa[q.
|
79
|
+
qa[q.id] = []
|
80
80
|
end
|
81
81
|
|
82
82
|
answers.each do |a|
|
83
|
-
qa[a.question.
|
83
|
+
qa[a.question.id] << a.answer.to_s.strip unless a.answer.blank?
|
84
84
|
end
|
85
85
|
|
86
86
|
qa
|
@@ -89,8 +89,9 @@ module Ask
|
|
89
89
|
private
|
90
90
|
|
91
91
|
def validate_required_questions
|
92
|
+
return if asker.blank?
|
92
93
|
asker.questions.required.each do |question|
|
93
|
-
if answers.select{|a| a.question_id == question.id}.all?{|a| a.
|
94
|
+
if answers.select{|a| a.question_id == question.id}.all?{|a| a.fails_required?}
|
94
95
|
errors[:base] << "\"#{question.name}\" is required"
|
95
96
|
end
|
96
97
|
end
|