survey 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/MIT-LICENSE +20 -0
- data/README.md +194 -0
- data/Rakefile +30 -0
- data/app/models/survey/answer.rb +34 -0
- data/app/models/survey/attempt.rb +60 -0
- data/app/models/survey/option.rb +34 -0
- data/app/models/survey/question.rb +24 -0
- data/app/models/survey/survey.rb +49 -0
- data/config/locales/en.yml +36 -0
- data/config/locales/pt-PT.yml +48 -0
- data/config/locales/pt.yml +48 -0
- data/lib/generators/survey/install_generator.rb +20 -0
- data/lib/generators/survey/survey_generator.rb +102 -0
- data/lib/generators/templates/active_admin.rb +46 -0
- data/lib/generators/templates/attempts_plain.rb +69 -0
- data/lib/generators/templates/attempts_views/_form.html.erb +18 -0
- data/lib/generators/templates/attempts_views/new.html.erb +11 -0
- data/lib/generators/templates/helper.rb +44 -0
- data/lib/generators/templates/migration.rb +56 -0
- data/lib/generators/templates/rails_admin.rb +3 -0
- data/lib/generators/templates/survey_plain.rb +54 -0
- data/lib/generators/templates/survey_views/_form.html.erb +61 -0
- data/lib/generators/templates/survey_views/_option_fields.html.erb +9 -0
- data/lib/generators/templates/survey_views/_question_fields.html.erb +15 -0
- data/lib/generators/templates/survey_views/edit.html.erb +2 -0
- data/lib/generators/templates/survey_views/index.html.erb +16 -0
- data/lib/generators/templates/survey_views/new.html.erb +2 -0
- data/lib/survey.rb +15 -0
- data/lib/survey/active_record.rb +28 -0
- data/lib/survey/engine.rb +6 -0
- data/lib/survey/version.rb +3 -0
- metadata +156 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
en:
|
2
|
+
surveys_controller:
|
3
|
+
create: Your Survey has been successfull created
|
4
|
+
update: Your Survey has been successfull updated
|
5
|
+
attempts_controller:
|
6
|
+
create: "Congratulations, you have responded to Survey."
|
7
|
+
surveys: Surveys
|
8
|
+
survey_details: Survey Details
|
9
|
+
questions: Questions
|
10
|
+
activerecord:
|
11
|
+
models:
|
12
|
+
survey:
|
13
|
+
survey: Survey
|
14
|
+
other: Surveys
|
15
|
+
attributes:
|
16
|
+
survey:
|
17
|
+
name: Name
|
18
|
+
finished: Finished
|
19
|
+
description: Short description
|
20
|
+
active: "Activated?"
|
21
|
+
attempts_number: Number of Maximum Attempts
|
22
|
+
questions_attributes: Questions
|
23
|
+
question:
|
24
|
+
text: Question Text
|
25
|
+
options_attributes: Options
|
26
|
+
options:
|
27
|
+
text: Option Text
|
28
|
+
correct: Correct
|
29
|
+
attempt:
|
30
|
+
answers_attributes: Answers
|
31
|
+
survey: Survey
|
32
|
+
answer:
|
33
|
+
attempt: Attempt
|
34
|
+
question: Question
|
35
|
+
option: Option
|
36
|
+
correct: Answer Correct?
|
@@ -0,0 +1,48 @@
|
|
1
|
+
pt-PT:
|
2
|
+
questions: Perguntas
|
3
|
+
survey_details: Detalhes do Questionário
|
4
|
+
surveys_controller:
|
5
|
+
create: O questionário foi criado com sucesso
|
6
|
+
update: O questionário foi atualizado com sucesso
|
7
|
+
attempts_controller:
|
8
|
+
create: "A sua resposta foi efetuada com sucesso."
|
9
|
+
surveys: Questionários
|
10
|
+
survey_details: Detalhes do Questionário
|
11
|
+
questions: Perguntas
|
12
|
+
activerecord:
|
13
|
+
models:
|
14
|
+
survey:
|
15
|
+
survey: Questionário
|
16
|
+
other: Questionários
|
17
|
+
question:
|
18
|
+
question: Pergunta
|
19
|
+
other: Perguntas
|
20
|
+
option:
|
21
|
+
option: Opção
|
22
|
+
other: Opções
|
23
|
+
attempt:
|
24
|
+
option: Resposta
|
25
|
+
other: Respostas
|
26
|
+
attributes:
|
27
|
+
survey:
|
28
|
+
name: Nome
|
29
|
+
finished: Acabado
|
30
|
+
description: Pequena Descrição
|
31
|
+
active: "Ativo?"
|
32
|
+
attempts_number: Número máximo de tentativas
|
33
|
+
questions_attributes: Perguntas
|
34
|
+
question:
|
35
|
+
text: Corpo da Pergunta
|
36
|
+
options_attributes: Opções
|
37
|
+
options:
|
38
|
+
text: Corpo da Opção
|
39
|
+
correct: Correta
|
40
|
+
attempt:
|
41
|
+
answers_attributes: Respostas
|
42
|
+
survey: Questionário
|
43
|
+
winner: Vencedor
|
44
|
+
answer:
|
45
|
+
attempt: Tentativa
|
46
|
+
question: Pergunta
|
47
|
+
option: Opção
|
48
|
+
correct: Resposta Correta?
|
@@ -0,0 +1,48 @@
|
|
1
|
+
pt:
|
2
|
+
questions: Perguntas
|
3
|
+
survey_details: Detalhes do Questionário
|
4
|
+
surveys_controller:
|
5
|
+
create: O questionário foi criado com sucesso
|
6
|
+
update: O questionário foi atualizado com sucesso
|
7
|
+
attempts_controller:
|
8
|
+
create: "A sua resposta foi efetuada com sucesso."
|
9
|
+
surveys: Questionários
|
10
|
+
survey_details: Detalhes do Questionário
|
11
|
+
questions: Perguntas
|
12
|
+
activerecord:
|
13
|
+
models:
|
14
|
+
survey:
|
15
|
+
survey: Questionário
|
16
|
+
other: Questionários
|
17
|
+
question:
|
18
|
+
question: Pergunta
|
19
|
+
other: Perguntas
|
20
|
+
option:
|
21
|
+
option: Opção
|
22
|
+
other: Opções
|
23
|
+
attempt:
|
24
|
+
option: Resposta
|
25
|
+
other: Respostas
|
26
|
+
attributes:
|
27
|
+
survey:
|
28
|
+
name: Nome
|
29
|
+
finished: Acabado
|
30
|
+
description: Pequena Descrição
|
31
|
+
active: "Ativo?"
|
32
|
+
attempts_number: Número máximo de tentativas
|
33
|
+
questions_attributes: Perguntas
|
34
|
+
question:
|
35
|
+
text: Corpo da Pergunta
|
36
|
+
options_attributes: Opções
|
37
|
+
options:
|
38
|
+
text: Corpo da Opção
|
39
|
+
correct: Correta
|
40
|
+
attempt:
|
41
|
+
answers_attributes: Respostas
|
42
|
+
survey: Questionário
|
43
|
+
winner: Vencedor
|
44
|
+
answer:
|
45
|
+
attempt: Tentativa
|
46
|
+
question: Pergunta
|
47
|
+
option: Opção
|
48
|
+
correct: Resposta Correta?
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Survey
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
def copy_migration
|
7
|
+
unless survey_migration_already_exists?
|
8
|
+
timestamp_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
|
9
|
+
copy_file "migration.rb", "db/migrate/#{timestamp_number}_create_survey.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def survey_migration_already_exists?
|
16
|
+
Dir.glob("#{File.join(destination_root, File.join("db", "migrate"))}/[0-9]*_*.rb").grep(/\d+_create_survey.rb$/).first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Survey
|
2
|
+
class SurveyGenerator < Rails::Generators::Base
|
3
|
+
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
TEMPLATES = ["active_admin", "rails_admin", "plain", "routes"]
|
7
|
+
|
8
|
+
argument :arguments,
|
9
|
+
:type => :array,
|
10
|
+
:default => [],
|
11
|
+
:banner => "< #{TEMPLATES.join("|")} > [options]"
|
12
|
+
|
13
|
+
def create_resolution
|
14
|
+
strategy = arguments.first
|
15
|
+
if TEMPLATES.include? strategy
|
16
|
+
send("generate_#{strategy}_resolution")
|
17
|
+
success_message(strategy)
|
18
|
+
else
|
19
|
+
error_message(strategy)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def generate_active_admin_resolution
|
26
|
+
copy_file "active_admin.rb", "app/admin/survey.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
def generate_rails_admin_resolution
|
30
|
+
scope = get_scope
|
31
|
+
copy_file "rails_admin.rb", "config/initializers/survey_rails_admin.rb"
|
32
|
+
template "attempts_plain.rb", "app/controllers/attempts_controller.rb"
|
33
|
+
template "helper.rb", "app/helpers/surveys_helper.rb"
|
34
|
+
directory "attempts_views", "app/views/attempts", :recursive => true
|
35
|
+
generate_routes_for(scope, true)
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_plain_resolution
|
39
|
+
scope = get_scope
|
40
|
+
prefix = scope ? "/#{scope}" : ""
|
41
|
+
template "survey_plain.rb", "app/controllers#{prefix}/surveys_controller.rb"
|
42
|
+
template "attempts_plain.rb", "app/controllers#{prefix}/attempts_controller.rb"
|
43
|
+
template "helper.rb", "app/helpers#{prefix}/surveys_helper.rb"
|
44
|
+
directory "survey_views", "app/views#{prefix}/surveys", :recursive => true
|
45
|
+
directory "attempts_views", "app/views#{prefix}/attempts", :recursive => true
|
46
|
+
generate_routes_for(scope)
|
47
|
+
end
|
48
|
+
|
49
|
+
def generate_routes_resolution
|
50
|
+
generate_routes_for(get_scope)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Error Handlers
|
54
|
+
def error_message(argument)
|
55
|
+
error_message = <<-CONTENT
|
56
|
+
This Resolution: '#{argument}' is not supported by Survey:
|
57
|
+
We only support Active Admin, Refinery and Active Scaffold
|
58
|
+
CONTENT
|
59
|
+
say error_message, :red
|
60
|
+
end
|
61
|
+
|
62
|
+
def success_message(argument)
|
63
|
+
say "Generation of #{argument.capitalize} Template Complete :) enjoy Survey", :green
|
64
|
+
end
|
65
|
+
|
66
|
+
def generate_routes_for(namespace, conditional=nil)
|
67
|
+
content_with_namespace = <<-CONTENT
|
68
|
+
|
69
|
+
namespace :#{namespace} do
|
70
|
+
resources :surveys
|
71
|
+
resources :attempts, :only => [:new, :create]
|
72
|
+
end
|
73
|
+
CONTENT
|
74
|
+
|
75
|
+
content_without_namespace = <<-CONTENT
|
76
|
+
|
77
|
+
resources :surveys
|
78
|
+
resources :attempts, :only => [:new, :create]
|
79
|
+
CONTENT
|
80
|
+
|
81
|
+
inject_into_file "config/routes.rb", "\n#{namespace ? content_with_namespace : content_without_namespace}",
|
82
|
+
:after => "#{Rails.application.class.to_s}.routes.draw do"
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_scope
|
86
|
+
return nil if arguments.size == 1 && arguments.first == 'plain'
|
87
|
+
namespace = arguments[1].split(':')
|
88
|
+
return namespace.last if namespace.size == 2 && namespace.first == 'namespace' && !namespace.blank?
|
89
|
+
say("Wrong parameter name: use namespace:<name> instead.", :red)
|
90
|
+
fail
|
91
|
+
end
|
92
|
+
|
93
|
+
def scope_module
|
94
|
+
get_scope ? "#{get_scope.titleize}::" : ""
|
95
|
+
end
|
96
|
+
|
97
|
+
def scope_namespace
|
98
|
+
get_scope ? "#{get_scope}_" : ""
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
ActiveAdmin.register Survey::Survey do
|
2
|
+
menu :label => I18n.t("surveys")
|
3
|
+
|
4
|
+
filter :name,
|
5
|
+
:as => :select,
|
6
|
+
:collection => proc {
|
7
|
+
Survey::Survey.select("distinct(name)").collect { |c|
|
8
|
+
[c.name, c.name]
|
9
|
+
}
|
10
|
+
}
|
11
|
+
filter :active,
|
12
|
+
:as => :select,
|
13
|
+
:collection => ["true", "false"]
|
14
|
+
|
15
|
+
filter :created_at
|
16
|
+
|
17
|
+
index do
|
18
|
+
column :name
|
19
|
+
column :description
|
20
|
+
column :active
|
21
|
+
column :attempts_number
|
22
|
+
column :finished
|
23
|
+
column :created_at
|
24
|
+
default_actions
|
25
|
+
end
|
26
|
+
|
27
|
+
form do |f|
|
28
|
+
f.inputs I18n.t("survey_details") do
|
29
|
+
f.input :name
|
30
|
+
f.input :description
|
31
|
+
f.input :active, :as => :select, :collection => ["true", "false"]
|
32
|
+
f.input :attempts_number
|
33
|
+
end
|
34
|
+
f.inputs I18n.t("questions") do
|
35
|
+
f.has_many :questions do |q|
|
36
|
+
q.input :text
|
37
|
+
q.has_many :options do |a|
|
38
|
+
a.input :text
|
39
|
+
a.input :correct
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
f.buttons
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class <%= scope_module %>AttemptsController < ApplicationController
|
2
|
+
|
3
|
+
helper '<%= get_scope ? "#{get_scope}/" : ''%>surveys'
|
4
|
+
|
5
|
+
before_filter :load_active_survey
|
6
|
+
before_filter :normalize_attempts_data, :only => :create
|
7
|
+
|
8
|
+
def new
|
9
|
+
@participant = current_user # you have to decide what to do here
|
10
|
+
|
11
|
+
unless @survey.nil?
|
12
|
+
@attempt = @survey.attempts.new
|
13
|
+
@attempt.answers.build
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def create
|
18
|
+
@attempt = @survey.attempts.new(attempt_params)
|
19
|
+
@attempt.participant = current_user
|
20
|
+
|
21
|
+
if @attempt.valid? && @attempt.save
|
22
|
+
redirect_to view_context.new_attempt, alert: I18n.t("attempts_controller.#{action_name}")
|
23
|
+
else
|
24
|
+
render :action => :new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def load_active_survey
|
31
|
+
@survey = Survey::Survey.active.first
|
32
|
+
end
|
33
|
+
|
34
|
+
def normalize_attempts_data
|
35
|
+
normalize_data!(params[:survey_attempt][:answers_attributes])
|
36
|
+
end
|
37
|
+
|
38
|
+
def normalize_data!(hash)
|
39
|
+
multiple_answers = []
|
40
|
+
last_key = hash.keys.last.to_i
|
41
|
+
|
42
|
+
hash.keys.each do |k|
|
43
|
+
if hash[k]['option_id'].is_a?(Array)
|
44
|
+
if hash[k]['option_id'].size == 1
|
45
|
+
hash[k]['option_id'] = hash[k]['option_id'][0]
|
46
|
+
next
|
47
|
+
else
|
48
|
+
multiple_answers << k if hash[k]['option_id'].size > 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
multiple_answers.each do |k|
|
54
|
+
hash[k]['option_id'][1..-1].each do |o|
|
55
|
+
last_key += 1
|
56
|
+
hash[last_key.to_s] = hash[k].merge('option_id' => o)
|
57
|
+
end
|
58
|
+
hash[k]['option_id'] = hash[k]['option_id'].first
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def attempt_params
|
63
|
+
rails4? ? params_whitelist : params[:survey_attempt]
|
64
|
+
end
|
65
|
+
|
66
|
+
def params_whitelist
|
67
|
+
params.require(:survey_attempt).permit(Survey::Attempt::AccessibleAttributes)
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<h1>Survey <%= @survey.name %></h1>
|
2
|
+
<%= form_for(@attempt, :url => attempt_scope(@attempt)) do |f| %>
|
3
|
+
<%= f.fields_for :answers do |builder| %>
|
4
|
+
<ul>
|
5
|
+
<% @survey.questions.each_with_index do |question, index| %>
|
6
|
+
<li>
|
7
|
+
<p><%= question.text %></p>
|
8
|
+
<%= hidden_field_tag "survey_attempt[answers_attributes][#{index}][question_id]", question.id %>
|
9
|
+
<% question.options.each do |option| %>
|
10
|
+
<%= check_box_tag "survey_attempt[answers_attributes][#{index}][option_id][]", option.id %>
|
11
|
+
<%= option.text %> <br/ >
|
12
|
+
<% end -%>
|
13
|
+
</li>
|
14
|
+
<% end -%>
|
15
|
+
</ul>
|
16
|
+
<% end -%>
|
17
|
+
<%= f.submit "Submit" %>
|
18
|
+
<% end -%>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% if @survey.nil? %>
|
2
|
+
<p>
|
3
|
+
<%= @participant.email %> there are not Active Surveys right now.
|
4
|
+
</p>
|
5
|
+
<% elsif @survey.avaliable_for_participant?(@participant) %>
|
6
|
+
<%= render 'form' %>
|
7
|
+
<% else %>
|
8
|
+
<p>
|
9
|
+
<%= @participant.email %> spent all the possible attempts to answer this Survey
|
10
|
+
</p>
|
11
|
+
<% end -%>
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module <%= scope_module %>SurveysHelper
|
2
|
+
def link_to_remove_field(name, f)
|
3
|
+
f.hidden_field(:_destroy) +
|
4
|
+
link_to_function(raw(name), "removeField(this)", :id =>"remove-attach")
|
5
|
+
end
|
6
|
+
|
7
|
+
def new_survey
|
8
|
+
new_<%= scope_namespace %>survey_path
|
9
|
+
end
|
10
|
+
|
11
|
+
def edit_survey(resource)
|
12
|
+
edit_<%= scope_namespace %>survey_path(resource)
|
13
|
+
end
|
14
|
+
|
15
|
+
def survey_scope(resource)
|
16
|
+
if action_name =~ /new|create/
|
17
|
+
<%= scope_namespace %>surveys_path(resource)
|
18
|
+
elsif action_name =~ /edit|update/
|
19
|
+
<%= scope_namespace %>survey_path(resource)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def new_attempt
|
24
|
+
new_<%= scope_namespace %>attempt_path
|
25
|
+
end
|
26
|
+
|
27
|
+
def attempt_scope(resource)
|
28
|
+
if action_name =~ /new|create/
|
29
|
+
<%= scope_namespace %>attempts_path(resource)
|
30
|
+
elsif action_name =~ /edit|update/
|
31
|
+
<%= scope_namespace %>attempt_path(resource)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def link_to_add_field(name, f, association)
|
36
|
+
new_object = f.object.class.reflect_on_association(association).klass.new
|
37
|
+
fields = f.fields_for(association, new_object,:child_index => "new_#{association}") do |builder|
|
38
|
+
render(association.to_s.singularize + "_fields", :f => builder)
|
39
|
+
end
|
40
|
+
link_to_function(name, "addField(this, \"#{association}\", \"#{escape_javascript(fields)}\")",
|
41
|
+
:id=>"add-attach",
|
42
|
+
:class=>"btn btn-small btn-info")
|
43
|
+
end
|
44
|
+
end
|