122 lines
3.0 KiB
Ruby
122 lines
3.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class TeamsController < ApplicationController
|
|
before_action :set_team, only: %i[show update]
|
|
before_action :authenticate_user!, only: %i[update]
|
|
before_action :require_team_update_actor!, only: %i[update]
|
|
before_action -> { require_writable_tournament!(@team.tournament) }, only: %i[update]
|
|
|
|
# GET /teams/1
|
|
def show
|
|
render json: @team
|
|
end
|
|
|
|
# PATCH/PUT /teams/1
|
|
def update
|
|
Team.transaction do
|
|
@team.assign_attributes(team_params)
|
|
assign_players_from_params if player_assignment_requested?
|
|
raise ActiveRecord::Rollback if performed?
|
|
|
|
@team.save!
|
|
end
|
|
return if performed?
|
|
|
|
push_sync_if_needed!(@team.tournament)
|
|
render json: @team
|
|
rescue ActiveRecord::RecordInvalid => e
|
|
render json: e.record.errors, status: :unprocessable_content
|
|
end
|
|
|
|
private
|
|
|
|
def set_team
|
|
@team = Team.find(params[:id])
|
|
end
|
|
|
|
def team_params
|
|
params.slice(:name).permit!
|
|
end
|
|
|
|
def player_assignment_requested?
|
|
params.key?(:player_email) || params.key?(:player_id) ||
|
|
params.key?(:player_emails) || params.key?(:player_ids)
|
|
end
|
|
|
|
def assign_players_from_params
|
|
unless tournament_owner?
|
|
render_forbidden_error
|
|
return
|
|
end
|
|
|
|
if params.key?(:player_emails)
|
|
@team.players = players_from_emails(params[:player_emails])
|
|
elsif params.key?(:player_ids)
|
|
@team.players = players_from_ids(params[:player_ids])
|
|
elsif params.key?(:player_email)
|
|
add_or_clear_player_from_email
|
|
else
|
|
add_or_clear_player_from_id
|
|
end
|
|
rescue ActiveRecord::RecordInvalid => e
|
|
render json: e.record.errors, status: :unprocessable_content
|
|
end
|
|
|
|
def players_from_emails(emails)
|
|
email_values(emails).map { |email| User.find_or_create_player_by_email!(email) }
|
|
end
|
|
|
|
def players_from_ids(player_ids)
|
|
id_values = Array.wrap(player_ids).map(&:to_s).map(&:strip).reject(&:blank?)
|
|
return [] if id_values.empty?
|
|
|
|
User.where(id: id_values).tap do |players|
|
|
unless players.size == id_values.uniq.size
|
|
raise ActiveRecord::RecordNotFound.new('Could not find all players', 'User')
|
|
end
|
|
end
|
|
end
|
|
|
|
def add_or_clear_player_from_email
|
|
email = params[:player_email].to_s.strip
|
|
if email.blank?
|
|
@team.players = []
|
|
return
|
|
end
|
|
|
|
add_player(User.find_or_create_player_by_email!(email))
|
|
end
|
|
|
|
def add_or_clear_player_from_id
|
|
player_id = params[:player_id].to_s.strip
|
|
if player_id.blank?
|
|
@team.players = []
|
|
return
|
|
end
|
|
|
|
add_player(User.find(player_id))
|
|
end
|
|
|
|
def add_player(player)
|
|
@team.players << player unless @team.player_ids.include?(player.id)
|
|
end
|
|
|
|
def email_values(emails)
|
|
Array.wrap(emails).map(&:to_s).map(&:strip).reject(&:blank?)
|
|
end
|
|
|
|
def require_team_update_actor!
|
|
return if tournament_owner? || @team.players.include?(current_user)
|
|
|
|
render_forbidden_error
|
|
end
|
|
|
|
def tournament_owner?
|
|
@team.owner == current_user
|
|
end
|
|
|
|
def push_sync_if_needed!(tournament)
|
|
TournamentSyncEnqueue.call(tournament)
|
|
end
|
|
end
|