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

# 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