From 690e497654e460ffae0a39d96aea98b312b8780b Mon Sep 17 00:00:00 2001 From: Jacob Cody Wimer Date: Sat, 25 Jan 2025 20:02:22 -0500 Subject: [PATCH] Fixed mat assignment rules to be db agnostic with comma delimited strings and upgraded test env db to mariadb 10.10 to match production. --- .../mat_assignment_rules_controller.rb | 24 ++++++------- app/models/mat.rb | 35 ++++++++++--------- app/models/mat_assignment_rule.rb | 29 +++++++++++---- app/views/mat_assignment_rules/_form.html.erb | 8 ++--- app/views/mat_assignment_rules/index.html.erb | 23 +++++------- ..._delimm_string_for_mat_assignment_rules.rb | 7 ++++ db/schema.rb | 8 ++--- deploy/docker-compose-test.yml | 2 +- 8 files changed, 76 insertions(+), 60 deletions(-) create mode 100644 db/migrate/20250126004721_use_comma_delimm_string_for_mat_assignment_rules.rb 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 @@
<%= form.label :weight_classes, "Allowed Weight Classes" %>
<% if @tournament.weights.any? %> - <% @tournament.weights.each do |weight| %> + <% @tournament.weights.sort_by{|w| w.max}.each do |weight| %>
- <%= check_box_tag "mat_assignment_rule[weight_classes][]", weight.id, @mat_assignment_rule.weight_classes.map(&:to_i).include?(weight.id) %> + <%= check_box_tag "mat_assignment_rule[weight_classes][]", weight.id, Array(@mat_assignment_rule.weight_classes).map(&:to_i).include?(weight.id) %> <%= label_tag "mat_assignment_rule_weight_classes_#{weight.id}", weight.max %>
<% end %> @@ -30,7 +30,7 @@ <% if @unique_bracket_positions.present? %> <% @unique_bracket_positions.each do |position| %>
- <%= check_box_tag "mat_assignment_rule[bracket_positions][]", position, @mat_assignment_rule.bracket_positions.include?(position) %> + <%= check_box_tag "mat_assignment_rule[bracket_positions][]", position, Array(@mat_assignment_rule.bracket_positions).include?(position) %> <%= label_tag "mat_assignment_rule_bracket_positions_#{position}", position %>
<% end %> @@ -45,7 +45,7 @@ <% if @unique_rounds.present? %> <% @unique_rounds.each do |round| %>
- <%= check_box_tag "mat_assignment_rule[rounds][]", round, @mat_assignment_rule.rounds.map(&:to_i).include?(round) %> + <%= check_box_tag "mat_assignment_rule[rounds][]", round, Array(@mat_assignment_rule.rounds).map(&:to_i).include?(round) %> <%= label_tag "mat_assignment_rule_rounds_#{round}", round %>
<% end %> diff --git a/app/views/mat_assignment_rules/index.html.erb b/app/views/mat_assignment_rules/index.html.erb index f501366..4b54150 100644 --- a/app/views/mat_assignment_rules/index.html.erb +++ b/app/views/mat_assignment_rules/index.html.erb @@ -5,30 +5,25 @@ Weight Classes (Max) Bracket Positions Rounds - <%= link_to ' New Mat Assignment Rule', new_tournament_mat_assignment_rule_path(@tournament), :class=>"fas fa-plus" %> + <%= link_to ' New Mat Assignment Rule', new_tournament_mat_assignment_rule_path(@tournament), class: "fas fa-plus" %> <% @mat_assignment_rules.each do |rule| %> <%= rule.mat.name %> - - - <% rule.weight_classes.each do |weight_id| %> - <% weight = @weights_by_id[weight_id] %> - <%= weight ? weight.max : "N/A" %><%= ", " unless weight_id == rule.weight_classes.last %> + <% Array(rule.weight_classes).each_with_index do |weight_id, index| %> + <% weight = @weights_by_id[weight_id.to_i] %> + <%= weight ? weight.max : "N/A" %> + <%= ", " unless index == Array(rule.weight_classes).size - 1 %> <% end %> - - - <%= rule.bracket_positions.join(", ") %> - <%= rule.rounds.join(", ") %> - - + <%= Array(rule.bracket_positions).join(", ") %> + <%= Array(rule.rounds).join(", ") %> - <%= link_to '', edit_tournament_mat_assignment_rule_path(@tournament, rule), :class=>"fas fa-edit" %> - <%= link_to '', tournament_mat_assignment_rule_path(@tournament, rule), method: :delete, data: { confirm: "Are you sure?" }, :class=>"fas fa-trash-alt" %> + <%= link_to '', edit_tournament_mat_assignment_rule_path(@tournament, rule), class: "fas fa-edit" %> + <%= link_to '', tournament_mat_assignment_rule_path(@tournament, rule), method: :delete, data: { confirm: "Are you sure?" }, class: "fas fa-trash-alt" %> <% end %> diff --git a/db/migrate/20250126004721_use_comma_delimm_string_for_mat_assignment_rules.rb b/db/migrate/20250126004721_use_comma_delimm_string_for_mat_assignment_rules.rb new file mode 100644 index 0000000..6b45dc7 --- /dev/null +++ b/db/migrate/20250126004721_use_comma_delimm_string_for_mat_assignment_rules.rb @@ -0,0 +1,7 @@ +class UseCommaDelimmStringForMatAssignmentRules < ActiveRecord::Migration[7.2] + def change + change_column :mat_assignment_rules, :weight_classes, :string + change_column :mat_assignment_rules, :bracket_positions, :string + change_column :mat_assignment_rules, :rounds, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index d83c5ff..17fbd60 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2025_01_22_142911) do +ActiveRecord::Schema[7.2].define(version: 2025_01_26_004721) do create_table "delayed_jobs", force: :cascade do |t| t.integer "priority", default: 0, null: false t.integer "attempts", default: 0, null: false @@ -31,9 +31,9 @@ ActiveRecord::Schema[7.2].define(version: 2025_01_22_142911) do create_table "mat_assignment_rules", force: :cascade do |t| t.integer "tournament_id", null: false t.integer "mat_id", null: false - t.json "weight_classes" - t.json "bracket_positions" - t.json "rounds" + t.string "weight_classes" + t.string "bracket_positions" + t.string "rounds" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["mat_id"], name: "index_mat_assignment_rules_on_mat_id", unique: true diff --git a/deploy/docker-compose-test.yml b/deploy/docker-compose-test.yml index 66664f5..beac441 100644 --- a/deploy/docker-compose-test.yml +++ b/deploy/docker-compose-test.yml @@ -41,7 +41,7 @@ services: test: curl http://127.0.0.1/ db: - image: mysql:5.7 + image: mariadb:10.10 ports: - "3306:3306" volumes: