From 109dfb177d4ecfc1985dc92df5a725edd29bb76a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 06:35:24 +0000 Subject: [PATCH 1/9] Initial plan From 4882fdf383e91040f8bb7af0aa94d9405e6f1c8d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Feb 2026 06:42:06 +0000 Subject: [PATCH 2/9] Rename organization_people to affiliations - models, controllers, routes, factories, specs Co-authored-by: maebeale <7607813+maebeale@users.noreply.github.com> --- app/controllers/affiliations_controller.rb | 36 +++++++++++++++++++ app/controllers/application_controller.rb | 4 +-- .../organization_people_controller.rb | 36 ------------------- app/controllers/organizations_controller.rb | 20 +++++------ app/controllers/people_controller.rb | 30 ++++++++-------- app/controllers/users_controller.rb | 4 +-- ...{organization_person.rb => affiliation.rb} | 10 +++--- app/models/organization.rb | 10 +++--- app/models/person.rb | 26 ++++++-------- ....html.erb => _affiliation_fields.html.erb} | 0 ....html.erb => _affiliation_fields.html.erb} | 0 app/views/people/_form.html.erb | 12 +++---- .../people/sections/_affiliations.html.erb | 14 ++++++++ .../sections/_organization_people.html.erb | 16 --------- app/views/people/show.html.erb | 2 +- ....html.erb => _affiliation_fields.html.erb} | 0 config/routes.rb | 2 +- ...ame_organization_people_to_affiliations.rb | 5 +++ ...organization_people.rb => affiliations.rb} | 2 +- ...ion_person_spec.rb => affiliation_spec.rb} | 14 ++++---- 20 files changed, 121 insertions(+), 122 deletions(-) create mode 100644 app/controllers/affiliations_controller.rb delete mode 100644 app/controllers/organization_people_controller.rb rename app/models/{organization_person.rb => affiliation.rb} (88%) rename app/views/organizations/{_organization_person_fields.html.erb => _affiliation_fields.html.erb} (100%) rename app/views/people/{_organization_person_fields.html.erb => _affiliation_fields.html.erb} (100%) create mode 100644 app/views/people/sections/_affiliations.html.erb delete mode 100644 app/views/people/sections/_organization_people.html.erb rename app/views/users/{_organization_person_fields.html.erb => _affiliation_fields.html.erb} (100%) create mode 100644 db/migrate/20260215063711_rename_organization_people_to_affiliations.rb rename spec/factories/{organization_people.rb => affiliations.rb} (76%) rename spec/models/{organization_person_spec.rb => affiliation_spec.rb} (75%) diff --git a/app/controllers/affiliations_controller.rb b/app/controllers/affiliations_controller.rb new file mode 100644 index 000000000..b4e3a9ddc --- /dev/null +++ b/app/controllers/affiliations_controller.rb @@ -0,0 +1,36 @@ +class AffiliationsController < ApplicationController + before_action :set_affiliation, only: %i[ destroy ] + + def destroy + authorize! @affiliation, to: :destroy? + affiliation = Affiliation.find(params[:id]) + person = affiliation.person + destroyed = affiliation.destroy + + if destroyed + flash.now[:notice] = "Person has been removed from the organization." + else + flash.now[:alert] = "Unable to remove affiliation. Please contact AWBW." + end + + respond_to do |format| + format.turbo_stream do + if destroyed + render turbo_stream: turbo_stream.remove("affiliation_#{affiliation.id}") + else + render turbo_stream: turbo_stream.replace("flash_now", partial: "shared/flash_messages"), + status: :unprocessable_entity + end + end + format.html do + redirect_to generate_facilitator_user_path(person.user) + end + end + end + + private + + def set_affiliation + @affiliation = Affiliation.find(params[:id]) + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e3ed1feb4..878e793ad 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -69,8 +69,8 @@ def flush_lifecycle_events def preload_current_user_associations return unless current_user&.person - @current_user_active_org_people = current_user.person - .organization_people + @current_user_active_affiliations = current_user.person + .affiliations .active .includes(:organization) .load diff --git a/app/controllers/organization_people_controller.rb b/app/controllers/organization_people_controller.rb deleted file mode 100644 index 7671e7095..000000000 --- a/app/controllers/organization_people_controller.rb +++ /dev/null @@ -1,36 +0,0 @@ -class OrganizationPeopleController < ApplicationController - before_action :set_organization_person, only: %i[ destroy ] - - def destroy - authorize! @organization_person, to: :destroy? - organization_person = OrganizationPerson.find(params[:id]) - person = organization_person.person - destroyed = organization_person.destroy - - if destroyed - flash.now[:notice] = "Person has been removed from the organization." - else - flash.now[:alert] = "Unable to remove organization person. Please contact AWBW." - end - - respond_to do |format| - format.turbo_stream do - if destroyed - render turbo_stream: turbo_stream.remove("organization_person_#{organization_person.id}") - else - render turbo_stream: turbo_stream.replace("flash_now", partial: "shared/flash_messages"), - status: :unprocessable_entity - end - end - format.html do - redirect_to generate_facilitator_user_path(person.user) - end - end - end - - private - - def set_organization_person - @organization_person = OrganizationPerson.find(params[:id]) - end -end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 4eb8d5288..765d8c39d 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -101,16 +101,16 @@ def set_form_variables .map { |fn, ln, id| [ "#{fn} #{ln}", id ] } if @organization.persisted? && @organization.errors.empty? - org_people = @organization.organization_people - org_people = org_people.includes(:person) unless org_people.loaded? - sorted = org_people.to_a - .sort_by { |op| - expired = op.inactive? || (op.end_date.present? && op.end_date < Date.current) + affiliations = @organization.affiliations + affiliations = affiliations.includes(:person) unless affiliations.loaded? + sorted = affiliations.to_a + .sort_by { |affiliation| + expired = affiliation.inactive? || (affiliation.end_date.present? && affiliation.end_date < Date.current) [ expired ? 1 : 0, - op.person&.first_name.to_s.downcase, - op.person&.last_name.to_s.downcase ] + affiliation.person&.first_name.to_s.downcase, + affiliation.person&.last_name.to_s.downcase ] } - @organization.organization_people.proxy_association.target.replace(sorted) + @organization.affiliations.proxy_association.target.replace(sorted) end end @@ -137,7 +137,7 @@ def set_organization @organization = Organization.includes( :organization_status, :windows_type, :addresses, { sectorable_items: :sector }, - organization_people: :person + affiliations: :person ).find(params[:id]) end @@ -155,7 +155,7 @@ def organization_params :sector_id, :_destroy ], - organization_people_attributes: [ + affiliations_attributes: [ :id, :person_id, :inactive, diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 62d0c63f6..6eb541f14 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -9,7 +9,7 @@ def index :avatar_attachment, :user, sectorable_items: :sector, - organization_people: :organization + affiliations: :organization ).references(:user)) filtered = base_scope.search_by_params(params.to_unsafe_h) .order(:first_name, :last_name) @@ -57,9 +57,9 @@ def show when "workshop_variation_ideas" @workshop_variation_ideas = @person.user&.workshop_variation_ideas_creator&.order(created_at: :desc)&.paginate(page: params[:page], per_page: per_page) || [] render partial: "people/sections/workshop_variation_ideas", locals: { person: @person, workshop_variation_ideas: @workshop_variation_ideas } - when "organization_people" - @organization_people = @person.organization_people.active.includes(organization: :logo_attachment).paginate(page: params[:page], per_page: per_page) - render partial: "people/sections/organization_people", locals: { person: @person, organization_people: @organization_people } + when "affiliations" + @affiliations = @person.affiliations.active.includes(organization: :logo_attachment).paginate(page: params[:page], per_page: per_page) + render partial: "people/sections/affiliations", locals: { person: @person, affiliations: @affiliations } end end end @@ -79,7 +79,7 @@ def edit { avatar_attachment: :blob }, { comments: [ :created_by, :updated_by ] }, { sectorable_items: :sector }, - organization_people: { organization: :logo_attachment } + affiliations: { organization: :logo_attachment } ).find(params[:id]).decorate authorize! @person set_form_variables @@ -175,18 +175,18 @@ def set_form_variables set_user # @person.build_user if @person.user.blank? # Build a fresh one if missing if @person.persisted? && @person.errors.empty? - org_people = @person.organization_people - org_people = org_people.includes(:organization) unless org_people.loaded? - sorted = org_people.to_a - .sort_by { |op| - expired = op.inactive? || (op.end_date.present? && op.end_date < Date.current) + affiliations = @person.affiliations + affiliations = affiliations.includes(:organization) unless affiliations.loaded? + sorted = affiliations.to_a + .sort_by { |affiliation| + expired = affiliation.inactive? || (affiliation.end_date.present? && affiliation.end_date < Date.current) [ expired ? 1 : 0, - op.start_date || Date.new(9999), - op.organization&.name.to_s.downcase ] + affiliation.start_date || Date.new(9999), + affiliation.organization&.name.to_s.downcase ] } - @person.organization_people.proxy_association.target.replace(sorted) + @person.affiliations.proxy_association.target.replace(sorted) end - @person.organization_people.build if @person.organization_people.empty? + @person.affiliations.build if @person.affiliations.empty? @all_sectors = Sector.published.order(:name) @sectors_collection = @all_sectors.pluck(:name, :id) @@ -372,7 +372,7 @@ def person_params :zip2, :notes ], - organization_people_attributes: [ + affiliations_attributes: [ :id, :organization_id, :position, diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 252e6bf74..6d47ddc22 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -267,7 +267,7 @@ def set_person def set_form_variables set_person - @user.person.organization_people.first || @user.person.organization_people.build if @user.person + @user.person.affiliations.first || @user.person.affiliations.build if @user.person organizations = authorized_scope(Organization.all) @organizations_array = organizations.order(:name).pluck(:name, :id) end @@ -333,8 +333,8 @@ def user_params :phone, :phone2, :phone3, :birthday, :best_time_to_call, :notes, # legacy to remove later ##### - organization_people_attributes: [ :id, :organization_id, :position, :title, :inactive, :primary_contact, :start_date, :end_date, :_destroy ], comments_attributes: [ :id, :body ], + affiliations_attributes: [ :id, :organization_id, :position, :title, :inactive, :primary_contact, :start_date, :end_date, :_destroy ], ) end end diff --git a/app/models/organization_person.rb b/app/models/affiliation.rb similarity index 88% rename from app/models/organization_person.rb rename to app/models/affiliation.rb index c1a0e3f6c..4cb45c248 100644 --- a/app/models/organization_person.rb +++ b/app/models/affiliation.rb @@ -1,4 +1,4 @@ -class OrganizationPerson < ApplicationRecord +class Affiliation < ApplicationRecord belongs_to :organization belongs_to :person, touch: true @@ -28,7 +28,7 @@ def name private def skip_if_duplicate - scope = OrganizationPerson.where( + scope = Affiliation.where( organization_id: organization_id, person_id: person_id, start_date: start_date, @@ -49,7 +49,7 @@ def set_inactive_from_dates def sync_organization_affiliation_dates org = organization - affiliations = org.organization_people.where.not(id: destroyed_by_association ? id : nil) + affiliations = org.affiliations.where.not(id: destroyed_by_association ? id : nil) earliest_start = affiliations.minimum(:start_date) has_active = affiliations.active.exists? @@ -67,7 +67,7 @@ def sync_organization_affiliation_dates end def deactivate_organization_if_no_active_people - return if organization.organization_people.active.exists? + return if organization.affiliations.active.exists? inactive_status = OrganizationStatus.find_by(name: "Inactive") return unless inactive_status @@ -81,7 +81,7 @@ def deactivate_organization_if_no_active_people resource_id: organization.id, resource_title: organization.name, change: "status_set_to_inactive", - reason: "no_active_organization_people" + reason: "no_active_affiliations" ) end end diff --git a/app/models/organization.rb b/app/models/organization.rb index bc4f5a677..fc79a0c91 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -6,8 +6,8 @@ class Organization < ApplicationRecord belongs_to :windows_type, optional: true has_many :addresses, as: :addressable, dependent: :destroy has_many :bookmarks, as: :bookmarkable, dependent: :destroy - has_many :organization_people, dependent: :restrict_with_error - has_many :people, through: :organization_people + has_many :affiliations, dependent: :restrict_with_error + has_many :people, through: :affiliations has_many :users, through: :people has_many :reports has_many :workshop_logs @@ -35,7 +35,7 @@ class Organization < ApplicationRecord validates :organization_status_id, presence: true validates :email, format: { with: URI::MailTo::EMAIL_REGEXP, message: "must be a valid email address" }, allow_blank: true validates :website_url, format: { with: /\Ahttps?:\/\/\S+\z/i, message: "must start with http:// or https://" }, allow_blank: true - validate :affiliation_dates_locked, if: -> { organization_people.any? && !Current.user&.super_user? } + validate :affiliation_dates_locked, if: -> { affiliations.any? && !Current.user&.super_user? } # Nested attributes accepts_nested_attributes_for :addresses, allow_destroy: true, @@ -43,7 +43,7 @@ class Organization < ApplicationRecord accepts_nested_attributes_for :sectorable_items, allow_destroy: true, reject_if: proc { |attrs| attrs["sector_id"].blank? } after_save :remove_duplicate_sectorable_items - accepts_nested_attributes_for :organization_people, allow_destroy: true, + accepts_nested_attributes_for :affiliations, allow_destroy: true, reject_if: proc { |attrs| attrs["person_id"].blank? } # SearchCop @@ -149,7 +149,7 @@ def affiliation_dates_locked end def leader - organization_people.find_by(position: 2) + affiliations.find_by(position: 2) end def remove_duplicate_sectorable_items diff --git a/app/models/person.rb b/app/models/person.rb index 598dc3d44..90e43da50 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -5,8 +5,8 @@ class Person < ApplicationRecord belongs_to :updated_by, class_name: "User" has_one :user, inverse_of: :person, dependent: :nullify - has_many :organization_people, dependent: :destroy - has_many :organizations, through: :organization_people + has_many :affiliations, dependent: :destroy + has_many :organizations, through: :affiliations has_many :communal_reports, through: :organizations, source: :reports has_many :windows_types, through: :organizations @@ -58,7 +58,7 @@ class Person < ApplicationRecord accepts_nested_attributes_for :sectorable_items, allow_destroy: true, reject_if: proc { |attrs| attrs["sector_id"].blank? } accepts_nested_attributes_for :user, update_only: true - accepts_nested_attributes_for :organization_people, allow_destroy: true, + accepts_nested_attributes_for :affiliations, allow_destroy: true, reject_if: proc { |attrs| attrs["organization_id"].blank? } accepts_nested_attributes_for :comments, reject_if: proc { |attrs| attrs["body"].blank? } @@ -76,18 +76,18 @@ class Person < ApplicationRecord scope :published, -> { searchable.with_active_affiliations } scope :searchable, ->(searchable = nil) { searchable ? where(profile_is_searchable: searchable) : where(profile_is_searchable: true) } scope :with_active_affiliations, -> { - joins(:organization_people) - .merge(OrganizationPerson.active) + joins(:affiliations) + .merge(Affiliation.active) .distinct } scope :organization_name, ->(organization_name) { return all if organization_name.blank? - left_joins(organization_people: :organization) + left_joins(affiliations: :organization) .where("organizations.name LIKE ?", "%#{sanitize_sql_like(organization_name)}%") .distinct } scope :organization_id, ->(organization_id) { - joins(:organization_people) - .where(organization_people: { organization_id: organization_id }) + joins(:affiliations) + .where(affiliations: { organization_id: organization_id }) .distinct } def self.search_by_params(params) @@ -102,7 +102,7 @@ def self.search_by_params(params) end def published? - profile_is_searchable? && organization_people.active.exists? + profile_is_searchable? && affiliations.active.exists? end def sector_list @@ -139,15 +139,11 @@ def phone_number end def has_liasion_position_for?(organization_id) - !organization_people.where(organization_id: organization_id, position: 1).first.nil? - end - - def published? - profile_is_searchable? && organization_people.active.exists? + !affiliations.where(organization_id: organization_id, position: 1).first.nil? end def primary_organization - organization_people + affiliations .active .order(updated_at: :desc) .first&.organization diff --git a/app/views/organizations/_organization_person_fields.html.erb b/app/views/organizations/_affiliation_fields.html.erb similarity index 100% rename from app/views/organizations/_organization_person_fields.html.erb rename to app/views/organizations/_affiliation_fields.html.erb diff --git a/app/views/people/_organization_person_fields.html.erb b/app/views/people/_affiliation_fields.html.erb similarity index 100% rename from app/views/people/_organization_person_fields.html.erb rename to app/views/people/_affiliation_fields.html.erb diff --git a/app/views/people/_form.html.erb b/app/views/people/_form.html.erb index 6060fdbeb..eff9a0c93 100644 --- a/app/views/people/_form.html.erb +++ b/app/views/people/_form.html.erb @@ -174,23 +174,23 @@
No affiliations listed.
+ <% end %> +<% end %> diff --git a/app/views/people/sections/_organization_people.html.erb b/app/views/people/sections/_organization_people.html.erb deleted file mode 100644 index e51e02cce..000000000 --- a/app/views/people/sections/_organization_people.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<%= turbo_frame_tag "person_organization_people_section" do %> - <% if organization_people.any? %> -No affiliations listed.
- <% end %> -<% end %> diff --git a/app/views/people/show.html.erb b/app/views/people/show.html.erb index 1b95244dd..b5d216741 100644 --- a/app/views/people/show.html.erb +++ b/app/views/people/show.html.erb @@ -100,7 +100,7 @@ <% if @person.profile_show_affiliations? %>Loading affiliations...
<% end %>