Skip to content
Snippets Groups Projects
person.rb 7.63 KiB
Newer Older
pabois's avatar
pabois committed
# == Schema Information
#
Sébastien Gaya's avatar
Sébastien Gaya committed
# Table name: university_people
pabois's avatar
pabois committed
#
pabois's avatar
pabois committed
#  id                 :uuid             not null, primary key
#  address            :string
#  biography          :text
#  birthdate          :date
#  city               :string
#  country            :string
#  description        :text
#  description_short  :text
#  email              :string
#  first_name         :string
#  gender             :integer
#  habilitation       :boolean          default(FALSE)
#  is_administration  :boolean
#  is_alumnus         :boolean          default(FALSE)
#  is_author          :boolean
#  is_researcher      :boolean
#  is_teacher         :boolean
#  last_name          :string
#  linkedin           :string
#  name               :string
#  phone_mobile       :string
#  phone_personal     :string
#  phone_professional :string
#  slug               :string
#  tenure             :boolean          default(FALSE)
#  twitter            :string
#  url                :string
#  zipcode            :string
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#  university_id      :uuid             not null, indexed
#  user_id            :uuid             indexed
pabois's avatar
pabois committed
#
# Indexes
#
Sébastien Gaya's avatar
Sébastien Gaya committed
#  index_university_people_on_university_id  (university_id)
#  index_university_people_on_user_id        (user_id)
pabois's avatar
pabois committed
#
# Foreign Keys
#
Arnaud Levy's avatar
Arnaud Levy committed
#  fk_rails_b47a769440  (user_id => users.id)
#  fk_rails_da35e70d61  (university_id => universities.id)
pabois's avatar
pabois committed
#
Sébastien Gaya's avatar
Sébastien Gaya committed
class University::Person < ApplicationRecord
pabois's avatar
pabois committed
  include Sanitizable
Arnaud Levy's avatar
Arnaud Levy committed
  include WithUniversity
Arnaud Levy's avatar
Arnaud Levy committed
  include WithGit
  include WithBlobs
  include WithEducation
  include WithExperiences
pabois's avatar
pabois committed
  include WithSlug
  include WithPicture
Sébastien Gaya's avatar
Sébastien Gaya committed
  include WithRoles
Arnaud Levy's avatar
Arnaud Levy committed
  include WithBlocks
Arnaud Levy's avatar
Arnaud Levy committed
  include WithPermalink
pabois's avatar
pabois committed

Arnaud Levy's avatar
Arnaud Levy committed
  LIST_OF_ROLES = [
    :administration,
    :teacher,
    :researcher,
    :alumnus,
    :author
  ].freeze
pabois's avatar
pabois committed
  enum gender: { male: 0, female: 1, non_binary: 2 }

Sébastien Gaya's avatar
Sébastien Gaya committed
  has_summernote :biography
pabois's avatar
pabois committed

  belongs_to :user, optional: true

Arnaud Levy's avatar
Arnaud Levy committed
  has_and_belongs_to_many :research_journal_papers,
                          class_name: 'Research::Journal::Paper',
                          join_table: :research_journal_papers_researchers,
pabois's avatar
pabois committed
                          foreign_key: :researcher_id

Arnaud Levy's avatar
Arnaud Levy committed
  has_many                :communication_website_posts,
                          class_name: 'Communication::Website::Post',
                          foreign_key: :author_id,
                          dependent: :nullify

Sébastien Gaya's avatar
Sébastien Gaya committed
  has_many                :communication_website_imported_authors,
Sébastien Gaya's avatar
Sébastien Gaya committed
                          class_name: "Communication::Website::Imported::Author",
Sébastien Gaya's avatar
Sébastien Gaya committed
                          foreign_key: :author_id,
                          dependent: :destroy

  has_many                :involvements,
                          class_name: 'University::Person::Involvement',
                          dependent: :destroy

pabois's avatar
pabois committed
  has_many                :author_websites,
Arnaud Levy's avatar
Arnaud Levy committed
                          -> { distinct },
                          through: :communication_website_posts,
                          source: :website

pabois's avatar
pabois committed
  has_many                :researcher_websites,
Arnaud Levy's avatar
Arnaud Levy committed
                          -> { distinct },
Arnaud Levy's avatar
Arnaud Levy committed
                          through: :research_journal_papers,
Arnaud Levy's avatar
Arnaud Levy committed
                          source: :websites

pabois's avatar
pabois committed
  has_many                :teacher_websites,
Arnaud Levy's avatar
Arnaud Levy committed
                          -> { distinct },
                          through: :education_programs,
                          source: :websites

  accepts_nested_attributes_for :involvements
Sébastien Gaya's avatar
Sébastien Gaya committed

Arnaud Levy's avatar
Arnaud Levy committed
  validates_presence_of   :first_name, :last_name
  validates_uniqueness_of :email,
                          scope: :university_id,
                          allow_blank: true,
                          if: :will_save_change_to_email?
  validates_format_of     :email,
                          with: Devise::email_regexp,
                          allow_blank: true,
                          if: :will_save_change_to_email?

Arnaud Levy's avatar
Arnaud Levy committed
  before_validation :sanitize_email, :prepare_name
Arnaud Levy's avatar
Arnaud Levy committed

  scope :ordered,         -> { order(:last_name, :first_name) }
Arnaud Levy's avatar
Arnaud Levy committed
  scope :administration,  -> { where(is_administration: true) }
Arnaud Levy's avatar
Arnaud Levy committed
  scope :teachers,        -> { where(is_teacher: true) }
  scope :researchers,     -> { where(is_researcher: true) }
Arnaud Levy's avatar
Arnaud Levy committed
  scope :alumni,          -> { where(is_alumnus: true) }
  scope :for_role, -> (role) { where("is_#{role}": true) }
Sébastien Gaya's avatar
Sébastien Gaya committed
  scope :for_program, -> (program_id) {
    left_joins(:education_programs_as_administrator, :education_programs_as_teacher)
      .where(education_programs: { id: program_id })
      .or(
        left_joins(:education_programs_as_administrator, :education_programs_as_teacher)
          .where(education_programs_as_teachers_university_people: { id: program_id })
      )
      .select("university_people.*")
      .distinct
  }
pabois's avatar
pabois committed
  scope :for_search_term, -> (term) {
    where("
      unaccent(concat(university_people.first_name, ' ', university_people.last_name)) ILIKE unaccent(:term) OR
      unaccent(concat(university_people.last_name, ' ', university_people.first_name)) ILIKE unaccent(:term) OR
      unaccent(university_people.first_name) ILIKE unaccent(:term) OR
      unaccent(university_people.last_name) ILIKE unaccent(:term) OR
      unaccent(university_people.email) ILIKE unaccent(:term) OR
pabois's avatar
pabois committed
      unaccent(university_people.phone_mobile) ILIKE unaccent(:term) OR
      unaccent(university_people.phone_personal) ILIKE unaccent(:term) OR
      unaccent(university_people.phone_professional) ILIKE unaccent(:term) OR
pabois's avatar
pabois committed
      unaccent(university_people.biography) ILIKE unaccent(:term) OR
      unaccent(university_people.description) ILIKE unaccent(:term) OR
      unaccent(university_people.description_short) ILIKE unaccent(:term) OR
      unaccent(university_people.twitter) ILIKE unaccent(:term) OR
pabois's avatar
pabois committed
      unaccent(university_people.linkedin) ILIKE unaccent(:term) OR
      unaccent(university_people.address) ILIKE unaccent(:term) OR
      unaccent(university_people.zipcode) ILIKE unaccent(:term) OR
      unaccent(university_people.city) ILIKE unaccent(:term) OR
pabois's avatar
pabois committed
      unaccent(university_people.url) ILIKE unaccent(:term)
    ", term: "%#{sanitize_sql_like(term)}%")
  }
pabois's avatar
pabois committed

  def to_s
    "#{first_name} #{last_name}"
pabois's avatar
pabois committed
  end
pabois's avatar
pabois committed

pabois's avatar
pabois committed
  def to_s_alphabetical
    "#{last_name} #{first_name}"
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def roles
    LIST_OF_ROLES.reject do |role|
Arnaud Levy's avatar
Arnaud Levy committed
      ! send "is_#{role}"
    end
  end

pabois's avatar
pabois committed
  def websites
    university.communication_websites
pabois's avatar
pabois committed
  end

  def git_path(website)
    "content/persons/#{slug}.html" if for_website?(website)
Arnaud Levy's avatar
Arnaud Levy committed
  end

  def git_dependencies(website)
    dependencies = [self]
    dependencies += active_storage_blobs
    dependencies += git_block_dependencies
    dependencies += [administrator, author, researcher, teacher]
Sébastien Gaya's avatar
Sébastien Gaya committed
    dependencies += website.menus.to_a
    dependencies += dependencies_through_blocks(website)
    dependencies
pabois's avatar
pabois committed
  end

  def administrator
    @administrator ||= University::Person::Administrator.find(id)
pabois's avatar
pabois committed
  end

  def author
    @author ||= University::Person::Author.find(id)
pabois's avatar
pabois committed
  end

  def researcher
    @researcher ||= University::Person::Researcher.find(id)
pabois's avatar
pabois committed
  end

  def teacher
    @teacher ||= University::Person::Teacher.find(id)
Arnaud Levy's avatar
Arnaud Levy committed
  end

  def for_website?(website)
Arnaud Levy's avatar
Arnaud Levy committed
    in_block_dependencies?(website) ||
    administrator.for_website?(website) ||
    author.for_website?(website) ||
    researcher.for_website?(website) ||
    teacher.for_website?(website)
Sébastien Gaya's avatar
Sébastien Gaya committed

Sébastien Gaya's avatar
Sébastien Gaya committed
  def full_street_address
    return nil if [address, zipcode, city].all?(&:blank?)
    [address, "#{zipcode} #{city} #{country}".strip].join(', ')
  end

Sébastien Gaya's avatar
Sébastien Gaya committed
  protected

  def explicit_blob_ids
    [picture&.blob_id]
  end

  def inherited_blob_ids
    [best_picture&.blob_id]
  end

Sébastien Gaya's avatar
Sébastien Gaya committed
  def sanitize_email
    self.email = self.email.to_s.downcase.strip
Sébastien Gaya's avatar
Sébastien Gaya committed
  end
Arnaud Levy's avatar
Arnaud Levy committed

  def prepare_name
    self.name = to_s
  end

  def permalink_config_key
    :persons
  end
pabois's avatar
pabois committed
end