diff --git a/app/controllers/mat_assignment_rules_controller.rb b/app/controllers/mat_assignment_rules_controller.rb index f9e831f..70de9dd 100644 --- a/app/controllers/mat_assignment_rules_controller.rb +++ b/app/controllers/mat_assignment_rules_controller.rb @@ -5,8 +5,7 @@ class MatAssignmentRulesController < ApplicationController def index @mat_assignment_rules = @tournament.mat_assignment_rules - # Create a hash mapping each Weight ID to its Weight object for quick lookups - @weights_by_id = @tournament.weights.index_by(&:id) + @weights_by_id = @tournament.weights.index_by(&:id) # For quick lookup end def new @@ -14,11 +13,6 @@ class MatAssignmentRulesController < ApplicationController load_form_data end - def destroy - @mat_assignment_rule.destroy - redirect_to tournament_mat_assignment_rules_path(@tournament), notice: 'Mat assignment rule was successfully deleted.' - end - def create @mat_assignment_rule = @tournament.mat_assignment_rules.build(mat_assignment_rule_params) load_form_data @@ -44,6 +38,11 @@ class MatAssignmentRulesController < ApplicationController end end + def destroy + @mat_assignment_rule.destroy + redirect_to tournament_mat_assignment_rules_path(@tournament), notice: 'Mat assignment rule was successfully deleted.' + end + private def set_tournament @@ -59,20 +58,17 @@ class MatAssignmentRulesController < ApplicationController end def mat_assignment_rule_params - # Ensure defaults to empty arrays for checkboxes params[:mat_assignment_rule][:weight_classes] ||= [] params[:mat_assignment_rule][:bracket_positions] ||= [] params[:mat_assignment_rule][:rounds] ||= [] - - # Permit parameters and normalize types + params.require(:mat_assignment_rule).permit(:mat_id, weight_classes: [], bracket_positions: [], rounds: []).tap do |whitelisted| - whitelisted[:weight_classes] = whitelisted[:weight_classes].map(&:to_i) - whitelisted[:rounds] = whitelisted[:rounds].map(&:to_i) - whitelisted[:bracket_positions] = whitelisted[:bracket_positions] # Assume these are strings + whitelisted[:weight_classes] = Array(whitelisted[:weight_classes]).map(&:to_i) + whitelisted[:rounds] = Array(whitelisted[:rounds]).map(&:to_i) + whitelisted[:bracket_positions] = Array(whitelisted[:bracket_positions]) end end - # Load data needed for the form def load_form_data @available_mats = @tournament.mats @unique_bracket_positions = @tournament.matches.select(:bracket_position).distinct.pluck(:bracket_position) diff --git a/app/models/mat.rb b/app/models/mat.rb index b9d5569..d3929c9 100644 --- a/app/models/mat.rb +++ b/app/models/mat.rb @@ -48,36 +48,37 @@ class Mat < ApplicationRecord def next_eligible_match # Start with all matches that are either unfinished (nil or 0), have a bout number, and are ordered by bout_number filtered_matches = tournament.matches - .where(finished: [nil, 0]) # finished is nil or 0 - .where(mat_id: nil) # mat_id is nil - .where.not(bout_number: nil) # bout_number is not nil - .order(:bout_number) - - # .where's are chained as ANDs - # cannot search for .where.not(loser1_name: "BYE") because it will not find any that are NULL + .where(finished: [nil, 0]) # finished is nil or 0 + .where(mat_id: nil) # mat_id is nil + .where.not(bout_number: nil) # bout_number is not nil + .order(:bout_number) + + # Filter out BYE matches filtered_matches = filtered_matches - .where("loser1_name != ? OR loser1_name IS NULL", "BYE") - .where("loser2_name != ? OR loser2_name IS NULL", "BYE") - - # Sequentially apply each rule, narrowing down the matches + .where("loser1_name != ? OR loser1_name IS NULL", "BYE") + .where("loser2_name != ? OR loser2_name IS NULL", "BYE") + + # Apply mat assignment rules mat_assignment_rules.each do |rule| if rule.weight_classes.any? - filtered_matches = filtered_matches.where(weight_id: rule.weight_classes) + # Ensure weight_classes is treated as an array + filtered_matches = filtered_matches.where(weight_id: Array(rule.weight_classes).map(&:to_i)) end if rule.bracket_positions.any? - filtered_matches = filtered_matches.where(bracket_position: rule.bracket_positions) + # Ensure bracket_positions is treated as an array + filtered_matches = filtered_matches.where(bracket_position: Array(rule.bracket_positions).map(&:to_s)) end if rule.rounds.any? - filtered_matches = filtered_matches.where(round: rule.rounds) + # Ensure rounds is treated as an array + filtered_matches = filtered_matches.where(round: Array(rule.rounds).map(&:to_i)) end end # Return the first match in filtered results, or nil if none are left - result = filtered_matches.first - result - end + filtered_matches.first + end def unfinished_matches diff --git a/app/models/mat_assignment_rule.rb b/app/models/mat_assignment_rule.rb index 0e2b57a..2fee9c4 100644 --- a/app/models/mat_assignment_rule.rb +++ b/app/models/mat_assignment_rule.rb @@ -2,11 +2,28 @@ class MatAssignmentRule < ApplicationRecord belongs_to :mat belongs_to :tournament - # Ensure default values for JSON fields - # because mysql doesn't allow this - after_initialize do - self.weight_classes ||= [] - self.bracket_positions ||= [] - self.rounds ||= [] + # Convert comma-separated values to arrays + def weight_classes + (super || "").split(",").map(&:to_i) + end + + def weight_classes=(value) + super(value.is_a?(Array) ? value.join(",") : value) + end + + def bracket_positions + (super || "").split(",") + end + + def bracket_positions=(value) + super(value.is_a?(Array) ? value.join(",") : value) + end + + def rounds + (super || "").split(",").map(&:to_i) + end + + def rounds=(value) + super(value.is_a?(Array) ? value.join(",") : value) end end diff --git a/app/views/mat_assignment_rules/_form.html.erb b/app/views/mat_assignment_rules/_form.html.erb index d917d23..65626c6 100644 --- a/app/views/mat_assignment_rules/_form.html.erb +++ b/app/views/mat_assignment_rules/_form.html.erb @@ -13,9 +13,9 @@