class Competitions::SaveTeamService < ApplicationService attr_reader :competition, :team, :creator, :params TEAM_MEMBER_ATTRIBUTES = %i[competition_id competition_team_id user_id role is_teacher created_at updated_at] def initialize(team, params) @team = team @competition = team.competition @creator = team.user @params = params end def call Competitions::SaveTeamForm.new(form_params).validate! new_record = team.new_record? is_teacher = team.user.is_teacher? ActiveRecord::Base.transaction do team.generate_invite_code if new_record team.team_type = 1 # 组队竞赛 team.name = params[:name].to_s.strip team.save! # 创建者 team.team_members.create!(user_id: creator.id, competition_id: competition.id, role: 1, is_teacher: is_teacher) if new_record update_teacher_team_members! update_member_team_members! end end private def update_teacher_team_members! teacher_ids = Array.wrap(params[:teacher_ids]).map(:to_i) old_teacher_ids = team.team_members.where(role: 3).pluck(:user_id) destroy_teacher_ids = old_teacher_ids - teacher_ids team.team_members.where(role: 3).where(user_id: destroy_teacher_ids).delete_all new_teacher_ids = teacher_ids - old_teacher_ids TeamMember.bulk_insert(*TEAM_MEMBER_ATTRIBUTES) do |worker| base_attr = { competition_id: competition.id, competition_team_id: team.id, role: 3, is_teacher: true } new_teacher_ids.each do |teacher_id| next if teacher_id == creator.id worker.add(base_attr.merge(user_id: teacher_id)) end end end def update_member_team_members! member_ids = Array.wrap(params[:member_ids]).map(:to_i) old_member_ids = team.team_members.where(role: 2).pluck(:user_id) destroy_member_ids = old_member_ids - member_ids team.team_members.where(role: 2).where(user_id: destroy_member_ids).delete_all new_member_ids = member_ids - old_member_ids TeamMember.bulk_insert(*TEAM_MEMBER_ATTRIBUTES) do |worker| base_attr = { competition_id: competition.id, competition_team_id: team.id, role: 2, is_teacher: false } new_member_ids.each do |member_id| next if member_id == creator.id worker.add(base_attr.merge(user_id: member_id)) end end end def form_params params.merge(competition: competition, team: team, creator: creator) end end