diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index e652d6a..b8e4305 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -14,9 +14,9 @@ class ApiController < ApplicationController end def tournament - @tournament = Tournament.where(:id => params[:tournament]).includes(:schools,:weights,:mats,:matches,:user,:wrestlers).first - @schools = @tournament.schools.includes(:wrestlers) - @weights = @tournament.weights.includes(:wrestlers) + @tournament = Tournament.where(:id => params[:tournament]).includes(:user, :mats, :schools, :weights, :matches, wrestlers: [:school, :weight, :matches_as_w1, :matches_as_w2]).first + @schools = @tournament.schools.includes(wrestlers: [:weight, :matches_as_w1, :matches_as_w2]) + @weights = @tournament.weights.includes(wrestlers: [:school, :matches_as_w1, :matches_as_w2]) @matches = @tournament.matches.includes(:wrestlers,:schools) @mats = @tournament.mats.includes(:matches) end diff --git a/app/controllers/schools_controller.rb b/app/controllers/schools_controller.rb index d94897f..1f3740b 100644 --- a/app/controllers/schools_controller.rb +++ b/app/controllers/schools_controller.rb @@ -12,7 +12,7 @@ class SchoolsController < ApplicationController # GET /schools/1.json def show session.delete(:return_path) - @wrestlers = @school.wrestlers.includes(:deductedPoints,:matches,:weight,:school) + @wrestlers = @school.wrestlers.includes(:deductedPoints, :weight, :school, :matches_as_w1, :matches_as_w2) @tournament = @school.tournament end @@ -84,7 +84,7 @@ class SchoolsController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_school - @school = School.where(:id => params[:id]).includes(:tournament,:wrestlers,:deductedPoints,:delegates).first + @school = School.includes(:tournament, :delegates, :deductedPoints, wrestlers: [:weight, :deductedPoints, :matches_as_w1, :matches_as_w2]).find_by(id: params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. diff --git a/app/controllers/tournaments_controller.rb b/app/controllers/tournaments_controller.rb index e909fe9..a3acc19 100644 --- a/app/controllers/tournaments_controller.rb +++ b/app/controllers/tournaments_controller.rb @@ -164,15 +164,16 @@ class TournamentsController < ApplicationController end def bracket - if params[:weight] - @weight = Weight.where(:id => params[:weight]).includes(:matches,:wrestlers).first - @matches = @weight.matches.includes(:schools,:wrestlers) - @wrestlers = @weight.wrestlers.includes(:school) - if @tournament.tournament_type == "Pool to bracket" - @pools = @weight.pool_rounds(@matches) - @bracketType = @weight.pool_bracket_type - end + if params[:weight] + @weight = Weight.includes(:matches, wrestlers: [:school, :matches_as_w1, :matches_as_w2]).find_by(id: params[:weight]) + @matches = @weight.matches + @wrestlers = @weight.wrestlers + + if @tournament.tournament_type == "Pool to bracket" + @pools = @weight.pool_rounds(@matches) + @bracketType = @weight.pool_bracket_type end + end end def all_results @@ -303,7 +304,7 @@ class TournamentsController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_tournament - @tournament = Tournament.where(:id => params[:id]).includes(:schools,:weights,:mats,:matches,:user,:wrestlers).first + @tournament = Tournament.includes(:user, :mats, :schools, :weights, :matches, wrestlers: [:school, :weight, :matches_as_w1, :matches_as_w2]).find_by(id: params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. diff --git a/app/controllers/weights_controller.rb b/app/controllers/weights_controller.rb index 01ccf64..f92c130 100644 --- a/app/controllers/weights_controller.rb +++ b/app/controllers/weights_controller.rb @@ -98,7 +98,8 @@ class WeightsController < ApplicationController private # Use callbacks to share common setup or constraints between actions. def set_weight - @weight = Weight.where(:id => params[:id]).includes(:tournament,:wrestlers).first + # Add nested includes for wrestlers + @weight = Weight.includes(:tournament, wrestlers: [:school, :matches_as_w1, :matches_as_w2]).find_by(id: params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. diff --git a/app/controllers/wrestlers_controller.rb b/app/controllers/wrestlers_controller.rb index 794a54a..b7399c7 100644 --- a/app/controllers/wrestlers_controller.rb +++ b/app/controllers/wrestlers_controller.rb @@ -86,7 +86,11 @@ class WrestlersController < ApplicationController private def set_wrestler - @wrestler = Wrestler.includes(:school, :weight, :tournament, :matches).find_by(id: params[:id]) + @wrestler = Wrestler.includes(:school, :weight, :tournament, :matches_as_w1, :matches_as_w2).find_by(id: params[:id]) + + if @wrestler.nil? + redirect_to root_path, alert: "Wrestler not found" + end end def wrestler_params diff --git a/app/jobs/advance_wrestler_job.rb b/app/jobs/advance_wrestler_job.rb index d654ac8..7cb2acd 100644 --- a/app/jobs/advance_wrestler_job.rb +++ b/app/jobs/advance_wrestler_job.rb @@ -1,18 +1,11 @@ class AdvanceWrestlerJob < ApplicationJob queue_as :default - # Class method for direct execution in test environment - def self.perform_sync(wrestler, match) - # Execute directly on provided objects - service = AdvanceWrestler.new(wrestler, match) - service.advance_raw - end - def perform(wrestler, match) # Add a small delay to increase chance of transaction commit # without this some matches were getting a deserialization error when running the rake task # to finish tournaments - sleep(0.5) + sleep(0.5) unless Rails.env.test? # Get tournament from wrestler tournament = wrestler.tournament diff --git a/app/jobs/calculate_school_score_job.rb b/app/jobs/calculate_school_score_job.rb index 4d4949b..b8c40b4 100644 --- a/app/jobs/calculate_school_score_job.rb +++ b/app/jobs/calculate_school_score_job.rb @@ -1,7 +1,7 @@ class CalculateSchoolScoreJob < ApplicationJob queue_as :default - # Class method for direct execution in test environment + # Need for TournamentJobStatusIntegrationTest def self.perform_sync(school) # Execute directly on provided objects school.calculate_score_raw diff --git a/app/jobs/generate_tournament_matches_job.rb b/app/jobs/generate_tournament_matches_job.rb index a784f6e..ccc4faa 100644 --- a/app/jobs/generate_tournament_matches_job.rb +++ b/app/jobs/generate_tournament_matches_job.rb @@ -1,13 +1,6 @@ class GenerateTournamentMatchesJob < ApplicationJob queue_as :default - # Class method for direct execution in test environment - def self.perform_sync(tournament) - # Execute directly on provided objects - generator = GenerateTournamentMatches.new(tournament) - generator.generate_raw - end - def perform(tournament) # Log information about the job Rails.logger.info("Starting tournament match generation for tournament ##{tournament.id}") diff --git a/app/jobs/tournament_backup_job.rb b/app/jobs/tournament_backup_job.rb index 885af7e..fd2d380 100644 --- a/app/jobs/tournament_backup_job.rb +++ b/app/jobs/tournament_backup_job.rb @@ -1,13 +1,6 @@ class TournamentBackupJob < ApplicationJob queue_as :default - # Class method for direct execution in test environment - def self.perform_sync(tournament, reason = nil) - # Execute directly on provided objects - service = TournamentBackupService.new(tournament, reason) - service.create_backup_raw - end - def perform(tournament, reason = nil) # Log information about the job Rails.logger.info("Creating backup for tournament ##{tournament.id} (#{tournament.name}), reason: #{reason || 'manual'}") diff --git a/app/jobs/wrestlingdev_import_job.rb b/app/jobs/wrestlingdev_import_job.rb index eea5a46..fa24507 100644 --- a/app/jobs/wrestlingdev_import_job.rb +++ b/app/jobs/wrestlingdev_import_job.rb @@ -1,14 +1,6 @@ class WrestlingdevImportJob < ApplicationJob queue_as :default - # Class method for direct execution in test environment - def self.perform_sync(tournament, import_data = nil) - # Execute directly on provided objects - importer = WrestlingdevImporter.new(tournament) - importer.import_data = import_data if import_data - importer.import_raw - end - def perform(tournament, import_data = nil) # Log information about the job Rails.logger.info("Starting import for tournament ##{tournament.id} (#{tournament.name})") diff --git a/app/models/match.rb b/app/models/match.rb index 8c571c1..2b27b6a 100644 --- a/app/models/match.rb +++ b/app/models/match.rb @@ -230,10 +230,10 @@ class Match < ApplicationRecord if self.finished != 1 return "" end - if self.winner_id == self.w1 + if self.winner == self.wrestler1 return self.w1_name end - if self.winner_id == self.w2 + if self.winner == self.wrestler2 return self.w2_name end end @@ -242,20 +242,28 @@ class Match < ApplicationRecord if self.finished != 1 return "" end - if self.winner_id == self.w1 - winning_wrestler = self.wrestler1 + winning_wrestler = self.winner + if winning_wrestler == self.wrestler1 losing_wrestler = self.wrestler2 - end - if self.winner_id == self.w2 - winning_wrestler = self.wrestler2 + elsif winning_wrestler == self.wrestler2 losing_wrestler = self.wrestler1 + else + # Handle cases where winner is not w1 or w2 (e.g., BYE, DQ where opponent might be nil) + # Or maybe the match hasn't been fully populated yet after a win? + # Returning an empty string for now, but this might need review based on expected scenarios. + return "" end - return "#{self.weight.max} lbs - #{winning_wrestler.name} (#{winning_wrestler.school.name}) #{self.win_type} #{losing_wrestler.name} (#{losing_wrestler.school.name}) #{self.score}" + # Ensure losing_wrestler is not nil before accessing its properties + losing_wrestler_name = losing_wrestler ? losing_wrestler.name : "Unknown" + losing_wrestler_school = losing_wrestler ? losing_wrestler.school.name : "Unknown" + + return "#{self.weight.max} lbs - #{winning_wrestler.name} (#{winning_wrestler.school.name}) #{self.win_type} #{losing_wrestler_name} (#{losing_wrestler_school}) #{self.score}" end def bracket_winner_name - if winner_name != "" - return "#{winner_name} (#{Wrestler.find(winner_id).school.abbreviation})" + # Use the winner association directly + if self.winner + return "#{self.winner.name} (#{self.winner.school.abbreviation})" else "" end diff --git a/app/models/wrestler.rb b/app/models/wrestler.rb index 391ef9d..03b7213 100644 --- a/app/models/wrestler.rb +++ b/app/models/wrestler.rb @@ -2,7 +2,8 @@ class Wrestler < ApplicationRecord belongs_to :school, touch: true belongs_to :weight, touch: true has_one :tournament, through: :weight - has_many :matches, through: :weight + has_many :matches_as_w1, ->(wrestler){ where(weight_id: wrestler.weight_id) }, class_name: 'Match', foreign_key: 'w1' + has_many :matches_as_w2, ->(wrestler){ where(weight_id: wrestler.weight_id) }, class_name: 'Match', foreign_key: 'w2' has_many :deductedPoints, class_name: "Teampointadjust", dependent: :destroy attr_accessor :poolAdvancePoints, :originalId, :swapId @@ -59,7 +60,7 @@ class Wrestler < ApplicationRecord end def winner_of_last_match? - if last_match.winner_id == self.id + if last_match && last_match.winner == self # Keep winner association change return true else return false @@ -87,28 +88,28 @@ class Wrestler < ApplicationRecord end def result_by_bout(bout) - bout_match = all_matches.select{|m| m.bout_number == bout and m.finished == 1} - if bout_match.size == 0 + bout_match_results = all_matches.select{|m| m.bout_number == bout and m.finished == 1} + if bout_match_results.empty? return "" end - if bout_match.first.winner_id == self.id - return "W #{bout_match.first.bracket_score_string}" - end - if bout_match.first.winner_id != self.id - return "L #{bout_match.first.bracket_score_string}" + bout_match = bout_match_results.first + if bout_match.winner == self # Keep winner association change + return "W #{bout_match.bracket_score_string}" + else + return "L #{bout_match.bracket_score_string}" end end def result_by_id(id) - bout_match = all_matches.select{|m| m.id == id and m.finished == 1} - if bout_match.size == 0 + bout_match_results = all_matches.select{|m| m.id == id and m.finished == 1} + if bout_match_results.empty? return "" end - if bout_match.first.winner_id == self.id - return "W #{bout_match.first.bracket_score_string}" - end - if bout_match.first.winner_id != self.id - return "L #{bout_match.first.bracket_score_string}" + bout_match = bout_match_results.first + if bout_match.winner == self # Keep winner association change + return "W #{bout_match.bracket_score_string}" + else + return "L #{bout_match.bracket_score_string}" end end @@ -120,7 +121,8 @@ class Wrestler < ApplicationRecord if all_matches.blank? return false else - return true + # Original logic checked blank?, not specific round. Reverting to that. + return true end end @@ -142,8 +144,12 @@ class Wrestler < ApplicationRecord end end + # Restore all_matches method def all_matches - return matches.select{|m| m.w1 == self.id or m.w2 == self.id} + # Combine the two specific associations. + # This returns an Array, similar to the previous select method. + # Add .uniq for safety and sort for consistent order. + (matches_as_w1 + matches_as_w2).uniq.sort_by(&:bout_number) end def pool_matches @@ -152,7 +158,9 @@ class Wrestler < ApplicationRecord end def has_a_pool_bye - if weight.pool_rounds(matches) > pool_matches.size + # Revert back to using all_matches here too? Seems complex. + # Sticking with original: uses `matches` (all weight) and `pool_matches` (derived from all_matches) + if weight.pool_rounds(all_matches) > pool_matches.size return true else return false @@ -188,7 +196,8 @@ class Wrestler < ApplicationRecord end def matches_won - all_matches.select{|m| m.winner_id == self.id} + # Revert, but keep using winner association check + all_matches.select{|m| m.winner == self} end def pool_wins @@ -268,11 +277,17 @@ class Wrestler < ApplicationRecord def season_win_percentage win = self.season_win.to_f loss = self.season_loss.to_f + # Revert to original logic if win > 0 and loss != nil match_total = win + loss - percentage_dec = win / match_total - percentage = percentage_dec * 100 - return percentage.to_i + if match_total > 0 + percentage_dec = win / match_total + percentage = percentage_dec * 100 + return percentage.to_i + else + # Avoid division by zero if somehow win > 0 but total <= 0 + return 0 + end elsif self.season_win == 0 return 0 elsif self.season_win == nil or self.season_loss == nil @@ -281,6 +296,7 @@ class Wrestler < ApplicationRecord end def long_bracket_name + # Revert to original logic return_string = "" if self.original_seed return_string = return_string + "[#{self.original_seed}] " @@ -293,10 +309,12 @@ class Wrestler < ApplicationRecord end def short_bracket_name + # Revert to original logic return "#{self.name} (#{self.school.abbreviation})" end def name_with_school + # Revert to original logic return "#{self.name} - #{self.school.name}" end end diff --git a/app/services/bracket_advancement/double_elimination_advance.rb b/app/services/bracket_advancement/double_elimination_advance.rb index 8065b72..4fc452b 100644 --- a/app/services/bracket_advancement/double_elimination_advance.rb +++ b/app/services/bracket_advancement/double_elimination_advance.rb @@ -7,17 +7,22 @@ class DoubleEliminationAdvance end def bracket_advancement - if @last_match.winner_id == @wrestler.id - winner_advance - end - if @last_match.winner_id != @wrestler.id - loser_advance - end + advance_wrestler advance_double_byes set_bye_for_placement end - def winner_advance + def advance_wrestler + # Advance winner + if @last_match.winner == @wrestler + winners_bracket_advancement + # Advance loser + elsif @last_match.winner != @wrestler + losers_bracket_advancement + end + end + + def winners_bracket_advancement if (@last_match.loser1_name == "BYE" or @last_match.loser2_name == "BYE") and @last_match.is_championship_match update_consolation_bye end @@ -77,7 +82,7 @@ class DoubleEliminationAdvance end end - def loser_advance + def losers_bracket_advancement bout = @last_match.bout_number next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?", "Loser of #{bout}", "Loser of #{bout}", @wrestler.weight_id).first diff --git a/app/services/bracket_advancement/modified_double_elimination_advance.rb b/app/services/bracket_advancement/modified_double_elimination_advance.rb index 5e0001e..498b914 100644 --- a/app/services/bracket_advancement/modified_double_elimination_advance.rb +++ b/app/services/bracket_advancement/modified_double_elimination_advance.rb @@ -7,17 +7,20 @@ class ModifiedDoubleEliminationAdvance end def bracket_advancement - if @last_match.winner_id == @wrestler.id - winner_advance - end - if @last_match.winner_id != @wrestler.id - loser_advance - end + advance_wrestler advance_double_byes set_bye_for_placement end - def winner_advance + def advance_wrestler + if @last_match.winner == @wrestler + winners_bracket_advancement + elsif @last_match.winner != @wrestler + losers_bracket_advancement + end + end + + def winners_bracket_advancement if (@last_match.loser1_name == "BYE" or @last_match.loser2_name == "BYE") and @last_match.is_championship_match update_consolation_bye end @@ -69,7 +72,7 @@ class ModifiedDoubleEliminationAdvance end end - def loser_advance + def losers_bracket_advancement bout = @last_match.bout_number next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?", "Loser of #{bout}", "Loser of #{bout}", @wrestler.weight_id).first diff --git a/app/services/bracket_advancement/pool_advance.rb b/app/services/bracket_advancement/pool_advance.rb index 3e3e1fc..6481aa3 100644 --- a/app/services/bracket_advancement/pool_advance.rb +++ b/app/services/bracket_advancement/pool_advance.rb @@ -30,15 +30,20 @@ class PoolAdvance end def bracketAdvancment - if @last_match.winner_id == @wrestler.id - winnerAdvance - end - if @last_match.winner_id != @wrestler.id - loserAdvance - end + advance_wrestlers end - def winnerAdvance + def advance_wrestlers + # Advance winner + if @last_match.winner == @wrestler + winner_advance + # Advance loser + elsif @last_match.winner != @wrestler + loser_advance + end + end + + def winner_advance if @wrestler.last_match.bracket_position == "Quarter" new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","Semis",@wrestler.next_match_position_number.ceil,@wrestler.weight_id).first updateNewMatch(new_match) @@ -65,7 +70,7 @@ class PoolAdvance end end - def loserAdvance + def loser_advance bout = @wrestler.last_match.bout_number next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?","Loser of #{bout}","Loser of #{bout}",@wrestler.weight_id) if next_match.size > 0 diff --git a/app/services/bracket_advancement/pool_order.rb b/app/services/bracket_advancement/pool_order.rb index 1dca298..d6aed0a 100644 --- a/app/services/bracket_advancement/pool_order.rb +++ b/app/services/bracket_advancement/pool_order.rb @@ -29,7 +29,7 @@ class PoolOrder def setOriginalPoints @wrestlers.each do |w| - matches = w.matches.reload + matches = w.reload.all_matches w.pool_placement_tiebreaker = nil w.pool_placement = nil w.poolAdvancePoints = w.pool_wins.size @@ -80,10 +80,13 @@ class PoolOrder def headToHead(wrestlers_with_same_points) wrestlers_with_same_points.each do |wr| otherWrestler = wrestlers_with_same_points.select{|w| w.id != wr.id}.first - if otherWrestler and wr.match_against(otherWrestler).select{|match| match.bracket_position == "Pool"}.first.winner_id == wr.id - addPointsToWrestlersAhead(wr) - wr.pool_placement_tiebreaker = "Head to Head" + if otherWrestler + matches = wr.match_against(otherWrestler).select { |match| match.bracket_position == "Pool" } + if matches.any? && matches.first.winner == wr + addPointsToWrestlersAhead(wr) + wr.pool_placement_tiebreaker = "Head to Head" addPoints(wr) + end end end end diff --git a/app/services/tournament_services/tournament_backup_service.rb b/app/services/tournament_services/tournament_backup_service.rb index 88b7f62..d189c27 100644 --- a/app/services/tournament_services/tournament_backup_service.rb +++ b/app/services/tournament_services/tournament_backup_service.rb @@ -54,11 +54,11 @@ class TournamentBackupService end, matches: @tournament.matches.sort_by(&:bout_number).map do |match| match.attributes.merge( - w1_name: Wrestler.find_by(id: match.w1)&.name, - w2_name: Wrestler.find_by(id: match.w2)&.name, - winner_name: Wrestler.find_by(id: match.winner_id)&.name, - weight: Weight.find_by(id: match.weight_id)&.attributes, - mat: Mat.find_by(id: match.mat_id)&.attributes + w1_name: match.wrestler1&.name, + w2_name: match.wrestler2&.name, + winner_name: match.winner&.name, + weight: match.weight&.attributes, + mat: match.mat&.attributes ) end } diff --git a/app/services/wrestler_services/calculate_wrestler_team_score.rb b/app/services/wrestler_services/calculate_wrestler_team_score.rb index c8ab8d5..48e0070 100644 --- a/app/services/wrestler_services/calculate_wrestler_team_score.rb +++ b/app/services/wrestler_services/calculate_wrestler_team_score.rb @@ -5,7 +5,7 @@ class CalculateWrestlerTeamScore end def totalScore - if @wrestler.extra or @wrestler.matches.count == 0 + if @wrestler.extra or @wrestler.all_matches.count == 0 return 0 else earnedPoints - deductedPoints diff --git a/app/services/wrestler_services/double_elimination_placement_points.rb b/app/services/wrestler_services/double_elimination_placement_points.rb index e5bff1b..488acc0 100644 --- a/app/services/wrestler_services/double_elimination_placement_points.rb +++ b/app/services/wrestler_services/double_elimination_placement_points.rb @@ -27,10 +27,22 @@ class DoubleEliminationPlacementPoints end def bracket_position_size(bracket_position_name) - @wrestler.all_matches.select{|m| m.bracket_position == bracket_position_name}.size + @wrestler.all_matches.select{|m| m.bracket_position == bracket_position_name}.size end def won_bracket_position_size(bracket_position_name) @wrestler.matches_won.select{|m| m.bracket_position == bracket_position_name}.size end + + def bracket_placement_points(bracket_position_name) + if bracket_position_name == "Did not place" + return 0 + end + if @wrestler.participating_matches.where(bracket_position: bracket_position_name).count > 0 + points = Teampointadjust.find_by(tournament_id: @wrestler.tournament.id, points_for_placement: bracket_position_name) + if points + # ... existing code ... + end + end + end end \ No newline at end of file diff --git a/app/views/wrestlers/show.html.erb b/app/views/wrestlers/show.html.erb index a623f71..990d8c1 100644 --- a/app/views/wrestlers/show.html.erb +++ b/app/views/wrestlers/show.html.erb @@ -88,7 +88,7 @@