diff --git a/app/controllers/matches_controller.rb b/app/controllers/matches_controller.rb index 0e252ee..f1f8089 100644 --- a/app/controllers/matches_controller.rb +++ b/app/controllers/matches_controller.rb @@ -89,7 +89,7 @@ class MatchesController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def match_params - params.require(:match).permit(:w1, :w2, :w1_stat, :w2_stat, :winner_id, :win_type, :score, :overtime_type, :finished) + params.require(:match).permit(:w1, :w2, :w1_stat, :w2_stat, :winner_id, :win_type, :score, :overtime_type, :finished, :round) end def check_access diff --git a/app/models/match.rb b/app/models/match.rb index 1f18b3b..19540ef 100644 --- a/app/models/match.rb +++ b/app/models/match.rb @@ -5,6 +5,11 @@ class Match < ApplicationRecord has_many :wrestlers, :through => :weight has_many :schools, :through => :wrestlers validate :score_validation, :win_type_validation, :bracket_position_validation, :overtime_type_validation + + # Callback to update finished_at when finished changes + # for some reason saved_change_to_finished? does not work on before_save like it does for after_update + before_save :update_finished_at, if: -> { will_save_change_to_attribute?(:finished) } + after_update :after_finished_actions, if: -> { saved_change_to_finished? || saved_change_to_winner_id? || @@ -20,7 +25,7 @@ class Match < ApplicationRecord if self.w2 wrestler2.touch end - if self.reload.finished == 1 && self.reload.winner_id != nil + if self.finished == 1 && self.winner_id != nil if self.mat self.mat.assign_next_match end @@ -282,4 +287,10 @@ class Match < ApplicationRecord "" end end + + private + + def update_finished_at + self.finished_at = finished == 1 ? Time.current.utc : nil + end end diff --git a/app/models/wrestler.rb b/app/models/wrestler.rb index f1f0a7e..11c0cf2 100644 --- a/app/models/wrestler.rb +++ b/app/models/wrestler.rb @@ -18,7 +18,7 @@ class Wrestler < ApplicationRecord def last_finished_match - all_matches.select{|m| m.finished == 1}.sort_by{|m| m.bout_number}.last + all_matches.select{|m| m.finished == 1}.sort_by{|m| m.finished_at}.last end def total_team_points diff --git a/app/views/matches/_matchstats.html.erb b/app/views/matches/_matchstats.html.erb index 9774c16..cbc2cad 100644 --- a/app/views/matches/_matchstats.html.erb +++ b/app/views/matches/_matchstats.html.erb @@ -23,13 +23,13 @@
School: <%= @wrestler1_school_name %> -
Last Match: <%= @wrestler1_last_match ? time_ago_in_words(@wrestler1_last_match.updated_at) : "N/A" %> +
Last Match: <%= @wrestler1_last_match && @wrestler1_last_match.finished_at ? time_ago_in_words(@wrestler1_last_match.finished_at) : "N/A" %> Name: <%= @wrestler2_name %>
School: <%= @wrestler2_school_name %> -
Last Match: <%= @wrestler2_last_match ? time_ago_in_words(@wrestler2_last_match.updated_at) : "N/A" %> +
Last Match: <%= @wrestler2_last_match && @wrestler2_last_match.finished_at ? time_ago_in_words(@wrestler2_last_match.finished_at) : "N/A" %> diff --git a/db/migrate/20250122142911_add_finished_at_to_matches.rb b/db/migrate/20250122142911_add_finished_at_to_matches.rb new file mode 100644 index 0000000..5a99809 --- /dev/null +++ b/db/migrate/20250122142911_add_finished_at_to_matches.rb @@ -0,0 +1,9 @@ +class AddFinishedAtToMatches < ActiveRecord::Migration[7.0] + def up + add_column :matches, :finished_at, :datetime + end + + def down + remove_column :matches, :finished_at + end +end diff --git a/db/schema.rb b/db/schema.rb index 8500fcd..d83c5ff 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_05_001725) do +ActiveRecord::Schema[7.2].define(version: 2025_01_22_142911) do create_table "delayed_jobs", force: :cascade do |t| t.integer "priority", default: 0, null: false t.integer "attempts", default: 0, null: false @@ -60,6 +60,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_01_05_001725) do t.string "loser2_name" t.integer "mat_id" t.string "overtime_type" + t.datetime "finished_at" t.index ["mat_id"], name: "index_matches_on_mat_id" t.index ["tournament_id"], name: "index_matches_on_tournament_id" t.index ["w1", "w2"], name: "index_matches_on_w1_and_w2" diff --git a/test/controllers/matches_controller_test.rb b/test/controllers/matches_controller_test.rb index 4428c79..c51e7ce 100644 --- a/test/controllers/matches_controller_test.rb +++ b/test/controllers/matches_controller_test.rb @@ -1,7 +1,8 @@ require 'test_helper' class MatchesControllerTest < ActionController::TestCase - include Devise::Test::ControllerHelpers + include Devise::Test::ControllerHelpers # Needed to sign in + include ActionView::Helpers::DateHelper # Needed for time ago in words setup do @tournament = Tournament.find(1) @@ -139,4 +140,37 @@ class MatchesControllerTest < ActionController::TestCase post_update_from_match_stat assert_redirected_to "/tournaments/#{@tournament.id}/matches" end + + test "stats page should load if a match does not have finished_at" do + create_double_elim_tournament_single_weight(14, "Regular Double Elimination 1-8") + user = users(:one) + @tournament.user_id = user.id + @tournament.save + matches = @tournament.matches.reload + match = matches.first + sign_in_owner + get :stat, params: { id: match.id } + assert_response :success + end + + test "stat page loads with the finished_at time ago in words when a match is already finished" do + create_double_elim_tournament_single_weight(14, "Regular Double Elimination 1-8") + user = users(:one) + @tournament.user_id = user.id + @tournament.save + matches = @tournament.matches.reload + match = matches.first + match.winner_id = match.w1 + match.finished = 1 + match.win_type = "Pin" + match.score = "2:03" + match.save + + finished_at = match.reload.finished_at + sign_in_owner + get :stat, params: { id: match.id } + # Check that the finished_at value is displayed on the page + assert_response :success + assert_includes @response.body, time_ago_in_words(finished_at), "time_ago_in_words(finished_at) should be displayed on the page" + end end diff --git a/test/models/match_test.rb b/test/models/match_test.rb index c22c69d..3f112c8 100644 --- a/test/models/match_test.rb +++ b/test/models/match_test.rb @@ -150,4 +150,40 @@ class MatchTest < ActiveSupport::TestCase match.save assert_equal 123, match.reload.pin_time_in_seconds end + + test "Match gets a finished_at value when finished changes and is 1" do + create_double_elim_tournament_single_weight(14, "Regular Double Elimination 1-8") + matches = @tournament.matches.reload + match = matches.first + match.winner_id = match.w1 + match.finished = 1 + match.win_type = "Pin" + match.score = "2:03" + match.save + # Assert finished_at is not nil + assert_not_nil match.reload.finished_at, "finished_at should not be nil when finished is set to 1" + end + + test "Match gets a finished_at value when finished changes and is 1 and finished_at does not change when winner id is changed" do + create_double_elim_tournament_single_weight(14, "Regular Double Elimination 1-8") + matches = @tournament.matches.reload + match = matches.first + match.winner_id = match.w1 + match.finished = 1 + match.win_type = "Pin" + match.score = "2:03" + match.save + + finished_at = match.reload.finished_at + + # Assert finished_at is not nil + assert_not_nil finished_at, "finished_at should not be nil when finished is set to 1" + + match.winner_id = match.w2 + match.save + + # Assert finished_at did not change + assert_equal match.reload.finished_at, finished_at + + end end