class Competitions::SaveTeamForm include ActiveModel::Model attr_accessor :competition, :team, :creator attr_accessor :name, :teacher_ids, :member_ids validates :name, presence: true validate :check_creator_enrollable def check_creator_enrollable return unless check_creator_identity_enrollable check_creator_multiple_enrollable end validate :check_teachers_enrollable def check_teachers_enrollable if competition.teacher_enroll_forbidden? # 禁止老师报名 return if creator.is_teacher? # 因为创建者有单独校验,所以这里跳过 return if teacher_ids.blank? if teacher_ids.present? errors.add(:teacher_ids, :enroll_forbidden) return end end self.teacher_ids = teacher_ids.map(&:to_i) all_teachers = creator.is_teacher? ? teacher_ids + [creator.id] : teacher_ids all_teachers.uniq! if all_teachers.size < competition.teacher_staff.minimum || all_teachers.size > competition.teacher_staff.maximum errors.add(:teacher_ids, :invalid_count, minimum: competition.teacher_staff.minimum, maximum: competition.teacher_staff.maximum) return end # 老师可多次报名,不检查 return unless competition.teacher_multiple_limited? # 存在已报名老师 enrolled_teacher_members = competition.team_members.where(user_id: all_teachers) .where.not(competition_team_id: team.id).pluck(:user_id) if enrolled_teacher_members.present? errors.add(:teacher_ids, :enrolled, names: User.where(id: enrolled_teacher_members).map(&:real_name).join(',')) return end end validate :check_members_enrollable def check_members_enrollable if competition.member_enroll_forbidden? # 禁止学生报名 return unless creator.is_teacher? # 因为创建者有单独校验,所以这里跳过 return if member_ids.blank? if member_ids.present? errors.add(:member_ids, :enroll_forbidden) return end end self.member_ids = member_ids.map(&:to_i) all_members = creator.is_teacher? ? member_ids : member_ids + [creator.id] all_members.uniq! if all_members.size < competition.member_staff.minimum || all_members.size > competition.member_staff.maximum errors.add(:member_ids, :invalid_count, minimum: competition.member_staff.minimum, maximum: competition.member_staff.maximum) return end # 成员可多次报名,不检查 return unless competition.member_multiple_limited? # 存在已报名成员 enrolled_members = competition.team_members.where(user_id: all_members) .where.not(competition_team_id: team.id).pluck(:user_id) if enrolled_members.present? errors.add(:member_ids, :enrolled, names: User.where(id: enrolled_members).map(&:real_name).join(',')) return end end private # 竞赛是否限制了职业 def check_creator_identity_enrollable if creator.is_teacher? && competition.teacher_enroll_forbidden? errors.add(:creator, :teacher_enroll_forbidden) return false elsif !creator.is_teacher? && competition.member_enroll_forbidden? errors.add(:creator, :member_enroll_forbidden) return false end true end # 创建者是否能多次报名 def check_creator_multiple_enrollable return unless team.new_record? # 编辑战队时不需要校验 return unless competition.enrolled?(creator) if (creator.is_teacher? && competition.teacher_multiple_limited?) || (!creator.is_teacher? && competition.member_multiple_limited?) errors.add(:creator, :enrolled) return false end true end end