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..350309fc7 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -8,13 +8,13 @@ def index base_scope = authorized_scope(Organization.includes(:windows_type, :organization_status, :sectors, :addresses, logo_attachment: :blob)) filtered = base_scope.search_by_params(params).order(:name) @organizations_count = filtered.count - @active_people_count = OrganizationPerson.active.where(organization_id: filtered.select(:id)).count("DISTINCT person_id, organization_id") + @active_people_count = Affiliation.active.where(organization_id: filtered.select(:id)).count("DISTINCT person_id, organization_id") @organizations = filtered.paginate(page: params[:page], per_page: per_page) org_ids = @organizations.map(&:id) - @affiliated_since = OrganizationPerson.where(organization_id: org_ids) + @affiliated_since = Affiliation.where(organization_id: org_ids) .group(:organization_id) .minimum(:start_date) - @active_people_counts = OrganizationPerson.active + @active_people_counts = Affiliation.active .where(organization_id: org_ids) .group(:organization_id) .distinct @@ -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..87a88984f 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,17 @@ 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.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 +371,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/decorators/organization_person_decorator.rb b/app/decorators/affiliation_decorator.rb similarity index 67% rename from app/decorators/organization_person_decorator.rb rename to app/decorators/affiliation_decorator.rb index c110346d0..86f3f24dc 100644 --- a/app/decorators/organization_person_decorator.rb +++ b/app/decorators/affiliation_decorator.rb @@ -1,4 +1,4 @@ -class OrganizationPersonDecorator < ApplicationDecorator +class AffiliationDecorator < ApplicationDecorator def detail(length: nil) "#{person.full_name}: #{title.presence || position} - #{organization.name}" end diff --git a/app/decorators/organization_decorator.rb b/app/decorators/organization_decorator.rb index 1a821611e..163388f0d 100644 --- a/app/decorators/organization_decorator.rb +++ b/app/decorators/organization_decorator.rb @@ -13,7 +13,7 @@ def title end def badges - earliest = organization_people.minimum(:start_date) || start_date + earliest = affiliations.minimum(:start_date) || start_date years = earliest ? (Time.zone.now.year - earliest.year) : nil badges = [] badges << badge("Legacy Organization (10+ years)", :legacy_facilitator) if years && years >= 10 diff --git a/app/decorators/person_decorator.rb b/app/decorators/person_decorator.rb index ae760db8b..82b867eb0 100644 --- a/app/decorators/person_decorator.rb +++ b/app/decorators/person_decorator.rb @@ -4,7 +4,7 @@ def title end def detail(length: nil) - text = organization_people.active.map { |op| "#{op.title.presence || op.position}, #{op.organization.name}" }.join(", ") + text = affiliations.active.map { |affiliation| "#{affiliation.title.presence || affiliation.position}, #{affiliation.organization.name}" }.join(", ") length ? text&.truncate(length) : text end @@ -30,7 +30,7 @@ def member_since_year end def badges - earliest = organization_people.minimum(:start_date) || member_since + earliest = affiliations.minimum(:start_date) || member_since years = earliest ? (Time.zone.now.year - earliest.year) : nil badges = [] badges << badge("Legacy Facilitator (10+ years)", :legacy_facilitator) if years && years >= 10 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/policies/organization_person_policy.rb b/app/policies/affiliation_policy.rb similarity index 87% rename from app/policies/organization_person_policy.rb rename to app/policies/affiliation_policy.rb index 740ed79a1..1f99ba949 100644 --- a/app/policies/organization_person_policy.rb +++ b/app/policies/affiliation_policy.rb @@ -1,4 +1,4 @@ -class OrganizationPersonPolicy < ApplicationPolicy +class AffiliationPolicy < ApplicationPolicy # See https://actionpolicy.evilmartians.io/#/writing_policies # def destroy? diff --git a/app/policies/monthly_report_policy.rb b/app/policies/monthly_report_policy.rb index 6caea8943..933873843 100644 --- a/app/policies/monthly_report_policy.rb +++ b/app/policies/monthly_report_policy.rb @@ -21,7 +21,7 @@ def member? @member ||= begin return false unless authenticated? return false unless record.organization - record.organization.organization_people.exists?(person_id: user.person_id) + record.organization.affiliations.exists?(person_id: user.person_id) end end diff --git a/app/policies/organization_policy.rb b/app/policies/organization_policy.rb index 80b266383..11d15c430 100644 --- a/app/policies/organization_policy.rb +++ b/app/policies/organization_policy.rb @@ -26,8 +26,8 @@ def show_workshop_logs? next relation.active if admin? next relation.none unless user&.person_id - relation.joins(:organization_people) - .where(organization_people: { person_id: user.person_id }) + relation.joins(:affiliations) + .where(affiliations: { person_id: user.person_id }) end private @@ -35,7 +35,7 @@ def show_workshop_logs? def member? @member ||= begin return false unless user&.person_id - record.organization_people.exists?(person_id: user.person_id) + record.affiliations.exists?(person_id: user.person_id) end end end diff --git a/app/policies/person_policy.rb b/app/policies/person_policy.rb index 0f8b9fc44..a01414d30 100644 --- a/app/policies/person_policy.rb +++ b/app/policies/person_policy.rb @@ -38,7 +38,7 @@ def owner? def has_associated_data? record.user.present? || - record.organization_people.exists? || + record.affiliations.exists? || record.stories_as_spotlighted_facilitator.exists? end end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 719a4c484..85a776ee3 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -22,7 +22,7 @@ def update_password? = authenticated? relation_scope(:colleagues) do |relation| next relation.has_access if admin? - colleague_person_ids = OrganizationPerson.where( + colleague_person_ids = Affiliation.where( organization_id: user.organization_ids ).select(:person_id) relation.where(person_id: colleague_person_ids).or(relation.where(id: user.id)) diff --git a/app/views/organizations/_organization_person_fields.html.erb b/app/views/organizations/_affiliation_fields.html.erb similarity index 98% rename from app/views/organizations/_organization_person_fields.html.erb rename to app/views/organizations/_affiliation_fields.html.erb index f478ddca8..fb04ab62e 100644 --- a/app/views/organizations/_organization_person_fields.html.erb +++ b/app/views/organizations/_affiliation_fields.html.erb @@ -64,7 +64,7 @@
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 %>