module OrgAdmin
class QuestionsController < ApplicationController
include Versionable
respond_to :html
after_action :verify_authorized
# GET /org_admin/templates/[:template_id]/phases/[:phase_id]/sections/[:section_id]/question/[:id]
def show
question = Question.includes(:annotations, :question_options, section: { phase: :template }).find(params[:id])
authorize question
render partial: 'show', locals: {
template: question.section.phase.template,
section: question.section,
question: question
}
end
# GET /org_admin/templates/[:template_id]/phases/[:phase_id]/sections/[:section_id]/question/[:id]/edit
def edit
question = Question.includes(:annotations, :question_options, section: { phase: :template }).find(params[:id])
authorize question
render partial: 'edit', locals: {
template: question.section.phase.template,
section: question.section,
question: question
}
end
# GET /org_admin/templates/[:template_id]/phases/[:phase_id]/sections/[:section_id]/questions/new
def new
section = Section.includes(:questions, phase: :template).find(params[:section_id])
nbr = section.questions.maximum(:number)
question = Question.new({ section_id: section.id, question_format: QuestionFormat.find_by(title: 'Text area'), number: nbr.present? ? nbr + 1 : 1 })
authorize question
render partial: 'form', locals: {
template: section.phase.template,
section: section,
question: question,
method: 'post',
url: org_admin_template_phase_section_questions_path(template_id: section.phase.template.id, phase_id: section.phase.id, id: section.id)
}
end
# POST /org_admin/templates/[:template_id]/phases/[:phase_id]/sections/[:section_id]/questions
def create
question = Question.new(question_params.merge({ section_id: params[:section_id] }))
authorize question
begin
question = get_new(question)
section = question.section
if question.save
flash[:notice] = success_message(_('question'), _('created'))
else
flash[:alert] = failed_create_error(question, _('question'))
end
rescue StandardError => e
flash[:alert] = _('Unable to create a new version of this template.')
end
redirect_to edit_org_admin_template_phase_path(template_id: section.phase.template.id, id: section.phase.id, section: section.id)
end
# PUT /org_admin/templates/[:template_id]/phases/[:phase_id]/sections/[:section_id]/questions/[:id]
def update
question = Question.find(params[:id])
authorize question
begin
question = get_modifiable(question)
# Need to reattach the incoming annotation's and question_options to the
# modifiable (versioned) question
attrs = question_params
attrs = transfer_associations(question) if question.id != params[:id]
# If the user unchecked all of the themes set the association to an empty array
# add check for number present to ensure this is not just an annotation
if attrs[:theme_ids].blank? && attrs[:number].present?
attrs[:theme_ids] = []
end
if question.update(attrs)
flash[:notice] = success_message(_('question'), _('updated'))
else
flash[:alert] = failed_update_error(question, _('question'))
end
rescue StandardError => e
puts e.message
flash[:alert] = _('Unable to create a new version of this template.')
end
if question.section.phase.template.customization_of.present?
redirect_to org_admin_template_phase_path({
template_id: question.section.phase.template.id,
id: question.section.phase.id,
section: question.section.id
})
else
redirect_to edit_org_admin_template_phase_path({
template_id: question.section.phase.template.id,
id: question.section.phase.id,
section: question.section.id
})
end
end
# DELETE /org_admin/templates/[:template_id]/phases/[:phase_id]/sections/[:section_id]/questions/[:id]
def destroy
question = Question.find(params[:id])
authorize question
begin
question = get_modifiable(question)
section = question.section
if question.destroy!
flash[:notice] = success_message(_('question'), _('deleted'))
else
flash[:alert] = failed_destroy_error(question, 'question')
end
rescue StandardError => e
flash[:alert] = _('Unable to create a new version of this template.')
end
redirect_to edit_org_admin_template_phase_path({
template_id: section.phase.template.id,
id: section.phase.id,
section: section.id
})
end
private
def question_params
params.require(:question)
.permit(:number, :text, :question_format_id, :option_comment_display,
:default_value,
question_options_attributes: %i[id number text is_default _destroy],
annotations_attributes: %i[id text org_id org type _destroy],
theme_ids: [])
end
# When a template gets versioned by changes to one of its questions we need to loop
# through the incoming params and ensure that the annotations and question_options
# get attached to the new question
def transfer_associations(question)
attrs = question_params
if attrs[:annotations_attributes].present?
attrs[:annotations_attributes].each_key do |key|
old_annotation = question.annotations.select do |a|
a.org_id.to_s == attrs[:annotations_attributes][key][:org_id] && a.type.to_s == attrs[:annotations_attributes][key][:type]
end
attrs[:annotations_attributes][key][:id] = old_annotation.first.id unless old_annotation.empty?
end
end
# TODO: This question_options id swap feel fragile. We cannot really match on any of the
# data elements because the user may have changed them so we rely on its position
# within the array/query since they should be equivalent.
if attrs[:question_options_attributes].present?
attrs[:question_options_attributes].each_key do |key|
attrs[:question_options_attributes][key][:id] = question.question_options[key.to_i].id.to_s if question.question_options[key.to_i].present?
end
end
attrs
end
end
end