| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 | # An Activity represents a single continuous event that the members of a group may attend.# An Activity belongs to a group, and has many participants.class Activity < ApplicationRecord  # @!attribute name  #   @return [String]  #     a short name for the activity.  #  # @!attribute description  #   @return [String]  #     a short text describing the activity. This text is always visible to  #     all users.  #  # @!attribute location  #   @return [String]  #     a short text describing where the activity will take place. Always  #     visible to all participants.  #  # @!attribute start  #   @return [TimeWithZone]  #     when the activity starts.  #  # @!attribute end  #   @return [TimeWithZone]  #     when the activity ends.  #  # @!attribute deadline  #   @return [TimeWithZone]  #     when the normal participants (everyone who isn't an organizer or group  #     leader) may not change their own attendance anymore. Disabled if set to  #     nil.  belongs_to :group  has_many :participants,    dependent: :destroy  has_many :people, through: :participants  validates :name, presence: true  validates :start, presence: true  validate  :deadline_before_start, unless: "self.deadline.blank?"  validate  :end_after_start,       unless: "self.end.blank?"  after_create :create_missing_participants!  # Get all people (not participants) that are organizers. Does not include  # group leaders, although they may modify the activity as well.  def organizers    self.participants.includes(:person).where(is_organizer: true)  end  # Determine whether the passed Person participates in the activity.  def is_participant?(person)    Participant.exists?(      activity_id: self.id,      person_id: person.id    )  end  # Determine whether the passed Person is an organizer for the activity.  def is_organizer?(person)    Participant.exists?(      person_id: person.id,      activity_id: self.id,      is_organizer: true    )  end  # Query the database to determine the amount of participants that are present/absent/unknown  def state_counts    self.participants.group(:attending).count  end  # Determine whether the passed Person may change this activity.  def may_change?(person)    person.is_admin ||    self.is_organizer?(person) ||    self.group.is_leader?(person)  end  # Create Participants for all People that  #  1. are members of the group  #  2. do not have Participants (and thus, no way to confirm) yet  def create_missing_participants!    people = self.group.people    if not self.participants.empty?      people = people.where('people.id NOT IN (?)', self.people.ids)    end    people.each do |p|      Participant.create(        activity: self,        person: p,      )    end  end  private  # Assert that the deadline for participants to change the deadline, if any,  # is set before the event starts.  def deadline_before_start    if self.deadline > self.start      errors.add(:deadline, 'must be before start')    end  end  # Assert that the activity's end, if any, occurs after the event's start.  def end_after_start    if self.end < self.start      errors.add(:end, 'must be after start')    end  endend
 |