From cf759a4cc742760f22404bd48ad2903c43d486a3 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 17 Feb 2024 02:42:12 -0600 Subject: [PATCH] Fixed my problem and now have correctly linked multiple form submission to more than one model and am able to update all relevant forms within the model. --- app/controllers/employers_controller.rb | 6 ++ app/controllers/forms_controller.rb | 3 +- app/controllers/onboardings_controller.rb | 47 ++++++++---- app/helpers/onboardings_helper.rb | 27 ++++--- app/models/employer.rb | 18 ++++- app/models/form.rb | 19 +++-- app/models/forms_role.rb | 6 ++ app/models/participant.rb | 11 ++- app/models/role.rb | 4 + app/models/vendor.rb | 2 + app/models/worker.rb | 3 + app/views/forms/_form.html.erb | 4 +- app/views/forms/index.html.erb | 2 +- app/views/onboardings/index.html.erb | 74 +++++++++---------- config/routes.rb | 30 +++++--- db/migrate/20240217055057_create_roles.rb | 9 +++ .../20240217055118_create_forms_roles.rb | 11 +++ .../20240217063851_add_note_to_forms_roles.rb | 5 ++ ...63857_add_date_completed_to_forms_roles.rb | 5 ++ db/schema.rb | 21 +++++- db/seeds.rb | 6 ++ test/fixtures/forms_roles.yml | 9 +++ test/fixtures/roles.yml | 7 ++ test/models/forms_role_test.rb | 7 ++ test/models/role_test.rb | 7 ++ 25 files changed, 253 insertions(+), 90 deletions(-) create mode 100644 app/models/forms_role.rb create mode 100644 app/models/role.rb create mode 100644 db/migrate/20240217055057_create_roles.rb create mode 100644 db/migrate/20240217055118_create_forms_roles.rb create mode 100644 db/migrate/20240217063851_add_note_to_forms_roles.rb create mode 100644 db/migrate/20240217063857_add_date_completed_to_forms_roles.rb create mode 100644 test/fixtures/forms_roles.yml create mode 100644 test/fixtures/roles.yml create mode 100644 test/models/forms_role_test.rb create mode 100644 test/models/role_test.rb diff --git a/app/controllers/employers_controller.rb b/app/controllers/employers_controller.rb index 18883b3..5e68121 100644 --- a/app/controllers/employers_controller.rb +++ b/app/controllers/employers_controller.rb @@ -101,6 +101,12 @@ class EmployersController < ApplicationController # Handle case where Employer is not found redirect_to some_path, alert: 'Employer not found.' end + + def onboarding + @employer = employer.find(params[:id]) + @onboarding_items = @employer.onboarding_items.includes(:form) + end + private diff --git a/app/controllers/forms_controller.rb b/app/controllers/forms_controller.rb index d20c809..82b98a8 100644 --- a/app/controllers/forms_controller.rb +++ b/app/controllers/forms_controller.rb @@ -43,8 +43,9 @@ class FormsController < ApplicationController end def form_params - params.require(:form).permit(:name, :required, :program, :role) + params.require(:form).permit(:name, :required, :program, role_ids: []) end + def check_admin redirect_to(root_path, alert: "Not authorized") unless current_user.admin? diff --git a/app/controllers/onboardings_controller.rb b/app/controllers/onboardings_controller.rb index e5aa26e..36bfc68 100644 --- a/app/controllers/onboardings_controller.rb +++ b/app/controllers/onboardings_controller.rb @@ -1,5 +1,5 @@ class OnboardingsController < ApplicationController - before_action :set_owner + before_action :set_owner, only: [:index, :submit_onboarding] def index # Make sure to set @owner first. If not found, you should redirect or handle the error appropriately. @@ -34,31 +34,50 @@ class OnboardingsController < ApplicationController end def submit_onboarding - params[:onboarding_items].each do |id, item_params| - onboarding_item = OnboardingItem.find(id) - onboarding_item.update(item_params.permit(:note, :date_completed)) + @owner = find_owner + onboarding_items_params.values.each do |item_params| + item = OnboardingItem.find_or_initialize_by(id: item_params.delete(:id)) + item.assign_attributes(item_params) + item.owner = @owner + item.save end - redirect_to polymorphic_path([@owner]), notice: 'Onboarding information updated successfully.' + redirect_to polymorphic_path(@owner), notice: 'Onboarding information updated successfully.' end - private def set_owner - # Example: finds "participant_id", sets @owner to the corresponding Participant object params.each do |name, value| if name =~ /(.+)_id$/ - model = $1.classify.constantize - @owner = model.find_by(id: value) - break if @owner # Break if owner is found + model_name = name.match(/(.+)_id$/)[1].classify + @owner = model_name.constantize.find(value) + break end end - redirect_to(root_path, alert: "Owner not found.") unless @owner + unless @owner + redirect_to root_path, alert: "Owner not found." + end end def onboarding_items_params - # Ensure you permit the correct parameters based on your form fields - params.require(:onboarding_item).permit(:form_id, :note, :date_completed) + params.permit(onboarding_items: [:id, :note, :date_completed]).fetch(:onboarding_items, {}) end -end + + def find_owner + # Check each expected owner type and find the corresponding record + if params[:participant_id] + @owner = Participant.find(params[:participant_id]) + elsif params[:employer_id] + @owner = Employer.find(params[:employer_id]) + elsif params[:worker_id] + @owner = Worker.find(params[:worker_id]) + elsif params[:vendor_id] + @owner = Vendor.find(params[:vendor_id]) + else + # Handle the case where no recognized owner parameter is provided + redirect_to root_path, alert: "Owner not found." + return nil + end + end +end \ No newline at end of file diff --git a/app/helpers/onboardings_helper.rb b/app/helpers/onboardings_helper.rb index 55abb41..85ccbac 100644 --- a/app/helpers/onboardings_helper.rb +++ b/app/helpers/onboardings_helper.rb @@ -1,13 +1,16 @@ module OnboardingsHelper - def submit_onboarding_path_helper(owner) - case owner - when Participant - submit_onboarding_participant_onboardings_path(owner) - when Worker - submit_onboarding_worker_onboardings_path(owner) - # Add cases for other owner types - else - root_path # Fallback path - end - end -end + def submit_onboarding_polymorphic_path(owner) + case owner + when Participant + submit_onboarding_participant_onboardings_path(owner) + when Worker + submit_onboarding_worker_onboardings_path(owner) + when Vendor + submit_onboarding_vendor_onboardings_path(owner) + when Employer + submit_onboarding_employer_onboardings_path(owner) + else + root_path # Default path if owner type is unrecognized + end + end +end \ No newline at end of file diff --git a/app/models/employer.rb b/app/models/employer.rb index 27a4baa..fb9112b 100644 --- a/app/models/employer.rb +++ b/app/models/employer.rb @@ -14,6 +14,8 @@ class Employer < ApplicationRecord "#{first_name} #{last_name}" end + has_many :onboarding_items, as: :owner + accepts_nested_attributes_for :onboarding_items class Employer < ApplicationRecord # Associations and other methods as before... @@ -30,5 +32,19 @@ class Employer < ApplicationRecord end end end -end + + def create_onboarding_items_for_forms + # Ensure there's a 'Role' model with an association set up between Forms and Roles. + employer_role = Role.find_by(name: 'Employer') + return unless employer_role + + # Fetch all forms associated with the 'Employer' role. + forms = Form.joins(:roles).where(roles: { id: employer_role.id }) + forms.each do |form| + self.onboarding_items.find_or_create_by(form: form) + end + end + +end + diff --git a/app/models/form.rb b/app/models/form.rb index 559a974..57855f3 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -1,6 +1,9 @@ class Form < ApplicationRecord # Assuming each form can have many onboarding items associated with different owners. has_many :onboarding_items + has_many :forms_roles + has_many :roles, through: :forms_roles + accepts_nested_attributes_for :forms_roles, allow_destroy: true validates :name, presence: true validates :role, inclusion: { in: %w[Participant Worker Vendor Employer] } @@ -11,13 +14,13 @@ class Form < ApplicationRecord private def update_onboarding_items - # Dynamically find the model class based on the role. Ensure 'role' matches your model name exactly. - owner_class = role.constantize - - # For each instance of the model, find or create an onboarding item linked to this form. - owner_class.find_each do |owner| - OnboardingItem.find_or_create_by(owner: owner, form: self) + roles.each do |role| + # Assuming `role.name` is 'Participant', 'Worker', 'Vendor', or 'Employer' + owner_class = role.name.constantize + + owner_class.find_each do |owner| + OnboardingItem.find_or_create_by(owner: owner, form: self) + end end end - end - \ No newline at end of file + end \ No newline at end of file diff --git a/app/models/forms_role.rb b/app/models/forms_role.rb new file mode 100644 index 0000000..5cfa688 --- /dev/null +++ b/app/models/forms_role.rb @@ -0,0 +1,6 @@ +class FormsRole < ApplicationRecord + belongs_to :form + belongs_to :role + attribute :note, :string + attribute :date_completed, :date +end diff --git a/app/models/participant.rb b/app/models/participant.rb index ad97982..c0ac085 100644 --- a/app/models/participant.rb +++ b/app/models/participant.rb @@ -31,10 +31,15 @@ class Participant < ApplicationRecord end def create_onboarding_items_for_forms - # Fetch all forms relevant to participants - forms = Form.where(role: 'Participant') + # Ensure there's a 'Role' model with an association set up between Forms and Roles. + participant_role = Role.find_by(name: 'Participant') + return unless participant_role + + # Fetch all forms associated with the 'Participant' role. + forms = Form.joins(:roles).where(roles: { id: participant_role.id }) forms.each do |form| - self.onboarding_items.create(form: form) + self.onboarding_items.find_or_create_by(form: form) end end + end \ No newline at end of file diff --git a/app/models/role.rb b/app/models/role.rb new file mode 100644 index 0000000..0a528dc --- /dev/null +++ b/app/models/role.rb @@ -0,0 +1,4 @@ +class Role < ApplicationRecord + has_many :forms_roles + has_many :forms, through: :forms_roles + end \ No newline at end of file diff --git a/app/models/vendor.rb b/app/models/vendor.rb index d8d072f..0128f76 100644 --- a/app/models/vendor.rb +++ b/app/models/vendor.rb @@ -4,6 +4,8 @@ class Vendor < ApplicationRecord has_many :service_contracts has_many :participants, through: :service_contracts has_many :bank_accounts, as: :owner + has_many :onboarding_items, as: :owner + accepts_nested_attributes_for :onboarding_items # Validations validates :tin, uniqueness: true, allow_blank: true, presence: true diff --git a/app/models/worker.rb b/app/models/worker.rb index 9fd1a12..cf93f6a 100644 --- a/app/models/worker.rb +++ b/app/models/worker.rb @@ -9,6 +9,9 @@ class Worker < ApplicationRecord has_many :employers, through: :participants, source: :employer has_many :employer_records, through: :participants + has_many :onboarding_items, as: :owner + accepts_nested_attributes_for :onboarding_items + # Validations validates :first_name, presence: true validates :last_name, presence: true diff --git a/app/views/forms/_form.html.erb b/app/views/forms/_form.html.erb index 0c2abf3..79a9e67 100644 --- a/app/views/forms/_form.html.erb +++ b/app/views/forms/_form.html.erb @@ -26,8 +26,8 @@
- <%= f.label :role, 'Who/Role', class: 'form-label' %> - <%= f.text_field :role, class: 'form-control', placeholder: 'Enter role' %> + <%= f.label :role_ids, 'Roles', class: 'form-label' %> + <%= f.collection_select :role_ids, Role.all, :id, :name, {}, { multiple: true, class: "form-control" } %>
diff --git a/app/views/forms/index.html.erb b/app/views/forms/index.html.erb index 5d7bc55..25495da 100644 --- a/app/views/forms/index.html.erb +++ b/app/views/forms/index.html.erb @@ -21,7 +21,7 @@ <%= form.name %> <%= form.required ? 'Required' : 'Optional' %> <%= form.program %> - <%= form.role %> + <%= form.roles.map(&:name).join(", ") %> <%= link_to edit_form_path(form), class: 'btn btn-info btn-sm' do %> diff --git a/app/views/onboardings/index.html.erb b/app/views/onboardings/index.html.erb index 9465e99..ba577c9 100644 --- a/app/views/onboardings/index.html.erb +++ b/app/views/onboardings/index.html.erb @@ -1,44 +1,42 @@
-
-
-

Onboarding Forms

- - <%= form_with(model: [@owner, OnboardingItem.new], url: submit_onboarding_path_helper(@owner), local: true, html: { class: 'needs-validation', novalidate: true }) do |form| %> - - - - - - - - - - <% @onboarding_items.each do |item| %> - - - - - - <% end %> - -
Form NameNotesDate Completed
<%= item.form.name %> - <%= text_area_tag "onboarding_items[#{item.id}][note]", item.note, class: "form-control", rows: 1 %> - - <%= date_field_tag "onboarding_items[#{item.id}][date_completed]", item.date_completed, class: "form-control" %> -
- -
- <%= form.submit 'Save', class: 'btn btn-dark' %> -
- <% end %> - -
- <%= link_to 'Back', polymorphic_path(@owner), class: 'btn btn-secondary' %> -
-
-
+

Onboarding

+<%= form_with(model: [@owner, OnboardingItem.new], url: submit_onboarding_polymorphic_path(@owner), local: true, html: { class: 'needs-validation', novalidate: true }) do |form| %> + + + + + + + + + + <% @onboarding_items.each_with_index do |item, index| %> + + + + + <%= hidden_field_tag "onboarding_items[#{index}][id]", item.id %> + + <% end %> + +
Form NameNotesDate Completed
<%= item.form.name %> + <%= text_area_tag "onboarding_items[#{index}][note]", item.note, id: "onboarding_items_#{index}_note", class: "form-control", rows: 1 %> + + <%= date_field_tag "onboarding_items[#{index}][date_completed]", item.date_completed, id: "onboarding_items_#{index}_date_completed", class: "form-control" %> +
+ +
+ <%= form.submit 'Save', class: 'btn btn-dark' %> +
+<% end %> + +
+ <%= link_to 'Back', polymorphic_path(@owner), class: 'btn btn-secondary' %> +
+ + <%# This is for resizing Notes area %>