You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
3.2 KiB
86 lines
3.2 KiB
# lib/questions_crafter/controller_helpers.rb
|
|
module QuestionsCrafter
|
|
module ControllerHelpers
|
|
def self.included(base)
|
|
base.class_eval do
|
|
extend ClassMethods
|
|
include InstanceMethods
|
|
end
|
|
end
|
|
|
|
module ClassMethods
|
|
# Class methods for controllers using QuestionsCrafter
|
|
def handles_questions(questions_class, on_success:)
|
|
underscore_questions_class_name = questions_class.name.underscore
|
|
define_method :questions_action_name do
|
|
underscore_questions_class_name
|
|
end
|
|
|
|
define_method :questions_class do
|
|
questions_class
|
|
end
|
|
|
|
define_method :questions_params do
|
|
question_definitions = questions_class.questions
|
|
permitted_params = question_definitions.map do |q|
|
|
if q[:type] == :checkbox_group
|
|
# For checkbox groups, permit an array of values
|
|
{ q[:name] => [] }
|
|
else
|
|
q[:name]
|
|
end
|
|
end
|
|
|
|
params.require(underscore_questions_class_name).permit(permitted_params)
|
|
end
|
|
|
|
# This is the action that gets injected into the controller with the name of the provided class
|
|
# but with underscore for example SignUpQuestions -> sign_up_questions
|
|
# It is meant to handle both the GET and the POST verbs
|
|
define_method underscore_questions_class_name do
|
|
if request.post?
|
|
send("#{underscore_questions_class_name}_post")
|
|
elsif request.get?
|
|
send("#{underscore_questions_class_name}_get")
|
|
end
|
|
end
|
|
|
|
# The POST action is used to handle the form submission and redisplay if there are still validation errors
|
|
define_method "#{underscore_questions_class_name}_post" do
|
|
questions_object = questions_class.new(questions_params)
|
|
success = false
|
|
method_res = if questions_object.valid?
|
|
success = true
|
|
send(on_success, questions_object)
|
|
end
|
|
# method_res has a 302 if a redirect happened in the on_success method
|
|
# TODO: should we halt the chain and handle the redirect after showing the confirmation with the read only form?
|
|
# Maybe we should be able to render the form with a confirmation message and a countdown to redirect
|
|
# TODO: What should we do here if all goes well? Display the form again with the values already filled but NON editable
|
|
|
|
render QuestionsCrafter::Ui::Components::QuestionsPage.new(
|
|
questions_object: questions_object,
|
|
form_url: "#",
|
|
form_method: :post,
|
|
read_only: success
|
|
) unless method_res == 302
|
|
end
|
|
|
|
# The GET action is used to display the form
|
|
define_method "#{underscore_questions_class_name}_get" do
|
|
questions_object = questions_class.new
|
|
render QuestionsCrafter::Ui::Components::QuestionsPage.new(
|
|
questions_object: questions_object,
|
|
form_url: "#",
|
|
form_method: :post,
|
|
read_only: false
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
module InstanceMethods
|
|
# Instance methods for controllers using QuestionsCrafter
|
|
end
|
|
end
|
|
end
|
|
|