123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- # A person represents a human being. A Person may be a Member in one or more
- # Groups, and be a Participant in any number of events of those Groups.
- # A Person may access the system by creating a User, and may have at most one
- # User.
- class Person < ApplicationRecord
- # @!attribute first_name
- # @return [String]
- # the person's first name. ('Vincent' in 'Vincent van Gogh'.)
- #
- # @!attribute infix
- # @return [String]
- # the part of a person's surname that is not taken into account when
- # sorting by surname. ('van' in 'Vincent van Gogh'.)
- #
- # @!attribute last_name
- # @return [String]
- # the person's surname. ('Gogh' in 'Vincent van Gogh'.)
- #
- # @!attribute birth_date
- # @return [Date]
- # the person's birth date.
- #
- # @!attribute email
- # @return [String]
- # the person's email address.
- #
- # @!attribute calendar_token
- # @return [String]
- # the calendar token that can be used to open this Person's events as an
- # ICAL file.
- #
- # @!attribute is_admin
- # @return [Boolean]
- # whether or not the person has administrative rights.
- has_one :user
- has_many :members,
- dependent: :destroy
- has_many :participants,
- dependent: :destroy
- has_many :groups, through: :members
- has_many :activities, through: :participants
- has_secure_token :calendar_token
- validates :email, uniqueness: true
- validates :first_name, presence: true
- validates :last_name, presence: true
- validate :birth_date_cannot_be_in_future
- before_validation :not_admin_if_nil
- before_save :update_user_email, if: :email_changed?
- # The person's full name.
- def full_name
- if self.infix
- [self.first_name, self.infix, self.last_name].join(' ')
- else
- [self.first_name, self.last_name].join(' ')
- end
- end
- # The person's reversed name, to sort by surname.
- def reversed_name
- if self.infix
- [self.last_name, self.infix, self.first_name].join(', ')
- else
- [self.last_name, self.first_name].join(', ')
- end
- end
- # All activities where this person is an organizer.
- def organized_activities
- self.participants.includes(:activity).where(is_organizer: true)
- end
- # Create multiple Persons from data found in a csv file, return those.
- def self.from_csv(content)
- reader = CSV.parse(content, {headers: true, skip_blanks: true})
- result = []
- reader.each do |row|
- p = Person.find_by(email: row['email'])
- if not p
- p = Person.new
- p.first_name = row['first_name']
- p.infix = row['infix']
- p.last_name = row['last_name']
- p.email = row['email']
- p.birth_date = Date.strptime(row['birth_date']) unless row['birth_date'].blank?
- p.save!
- end
- result << p
- end
- return result
- end
- private
- # Assert that the person's birth date, if any, lies in the past.
- def birth_date_cannot_be_in_future
- if self.birth_date && self.birth_date > Date.today
- errors.add(:birth_date, I18n.t('person.errors.cannot_future'))
- end
- end
- # Explicitly force nil to false in the admin field.
- def not_admin_if_nil
- self.is_admin ||= false
- end
- # Ensure the person's user email is updated at the same time as the person's
- # email.
- def update_user_email
- if not self.user.nil?
- self.user.update!(email: self.email)
- end
- end
- end
|