mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-03-25 01:14:43 +00:00
Added a turbo stream for the current and next match on mat stats page.
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
class Match < ApplicationRecord
|
class Match < ApplicationRecord
|
||||||
|
include ActionView::RecordIdentifier
|
||||||
|
|
||||||
belongs_to :tournament, touch: true
|
belongs_to :tournament, touch: true
|
||||||
belongs_to :weight, touch: true
|
belongs_to :weight, touch: true
|
||||||
belongs_to :mat, touch: true, optional: true
|
belongs_to :mat, touch: true, optional: true
|
||||||
@@ -10,6 +12,10 @@ class Match < ApplicationRecord
|
|||||||
# Callback to update finished_at when a match is finished
|
# Callback to update finished_at when a match is finished
|
||||||
before_save :update_finished_at
|
before_save :update_finished_at
|
||||||
|
|
||||||
|
# update mat show with correct match if bout board is reset
|
||||||
|
# this is done with a turbo stream
|
||||||
|
after_commit :broadcast_mat_assignment_change, if: :saved_change_to_mat_id?, on: [:create, :update]
|
||||||
|
|
||||||
# Enqueue advancement and related actions after the DB transaction has committed.
|
# Enqueue advancement and related actions after the DB transaction has committed.
|
||||||
# Using after_commit ensures any background jobs enqueued inside these callbacks
|
# Using after_commit ensures any background jobs enqueued inside these callbacks
|
||||||
# will see the committed state of the match (e.g. finished == 1). Enqueuing
|
# will see the committed state of the match (e.g. finished == 1). Enqueuing
|
||||||
@@ -50,7 +56,7 @@ class Match < ApplicationRecord
|
|||||||
errors.add(:winner_id, "cannot be blank")
|
errors.add(:winner_id, "cannot be blank")
|
||||||
end
|
end
|
||||||
if win_type == "Pin" and ! score.match(/^[0-5]?[0-9]:[0-5][0-9]/)
|
if win_type == "Pin" and ! score.match(/^[0-5]?[0-9]:[0-5][0-9]/)
|
||||||
errors.add(:score, "needs to be in time format MM:SS when win type is Pin example: 1:23 or 10:03")
|
errors.add(:score, "needs to be in time format MM:SS when win type is Pin example: 2:23, 0:25, 10:03")
|
||||||
end
|
end
|
||||||
if win_type == "Decision" or win_type == "Tech Fall" or win_type == "Major" and ! score.match(/^[0-9]?[0-9]-[0-9]?[0-9]/)
|
if win_type == "Decision" or win_type == "Tech Fall" or win_type == "Major" and ! score.match(/^[0-9]?[0-9]-[0-9]?[0-9]/)
|
||||||
errors.add(:score, "needs to be in Number-Number format when win type is Decision, Tech Fall, and Major example: 10-2")
|
errors.add(:score, "needs to be in Number-Number format when win type is Decision, Tech Fall, and Major example: 10-2")
|
||||||
@@ -334,4 +340,26 @@ class Match < ApplicationRecord
|
|||||||
self.finished_at = Time.current.utc
|
self.finished_at = Time.current.utc
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def broadcast_mat_assignment_change
|
||||||
|
old_mat_id, new_mat_id = saved_change_to_mat_id || previous_changes["mat_id"]
|
||||||
|
return unless old_mat_id || new_mat_id
|
||||||
|
|
||||||
|
[old_mat_id, new_mat_id].compact.uniq.each do |mat_id|
|
||||||
|
mat = Mat.find_by(id: mat_id)
|
||||||
|
next unless mat
|
||||||
|
|
||||||
|
Turbo::StreamsChannel.broadcast_update_to(
|
||||||
|
mat,
|
||||||
|
target: dom_id(mat, :current_match),
|
||||||
|
partial: "mats/current_match",
|
||||||
|
locals: {
|
||||||
|
mat: mat,
|
||||||
|
match: mat.unfinished_matches.first,
|
||||||
|
next_match: mat.unfinished_matches.second,
|
||||||
|
show_next_bout_button: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
37
app/views/mats/_current_match.html.erb
Normal file
37
app/views/mats/_current_match.html.erb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<% @mat = mat %>
|
||||||
|
<% @match = local_assigns[:match] || mat.unfinished_matches.first %>
|
||||||
|
<% @next_match = local_assigns[:next_match] || mat.unfinished_matches.second %>
|
||||||
|
<% @show_next_bout_button = local_assigns.key?(:show_next_bout_button) ? local_assigns[:show_next_bout_button] : true %>
|
||||||
|
|
||||||
|
<% @wrestlers = [] %>
|
||||||
|
<% if @match %>
|
||||||
|
<% if @match.w1 %>
|
||||||
|
<% @wrestler1_name = @match.wrestler1.name %>
|
||||||
|
<% @wrestler1_school_name = @match.wrestler1.school.name %>
|
||||||
|
<% @wrestler1_last_match = @match.wrestler1.last_match %>
|
||||||
|
<% @wrestlers.push(@match.wrestler1) %>
|
||||||
|
<% else %>
|
||||||
|
<% @wrestler1_name = "Not assigned" %>
|
||||||
|
<% @wrestler1_school_name = "N/A" %>
|
||||||
|
<% @wrestler1_last_match = nil %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if @match.w2 %>
|
||||||
|
<% @wrestler2_name = @match.wrestler2.name %>
|
||||||
|
<% @wrestler2_school_name = @match.wrestler2.school.name %>
|
||||||
|
<% @wrestler2_last_match = @match.wrestler2.last_match %>
|
||||||
|
<% @wrestlers.push(@match.wrestler2) %>
|
||||||
|
<% else %>
|
||||||
|
<% @wrestler2_name = "Not assigned" %>
|
||||||
|
<% @wrestler2_school_name = "N/A" %>
|
||||||
|
<% @wrestler2_last_match = nil %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% @tournament = @match.tournament %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if @match %>
|
||||||
|
<%= render "matches/matchstats" %>
|
||||||
|
<% else %>
|
||||||
|
<p>No matches assigned to this mat.</p>
|
||||||
|
<% end %>
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
<h3>Mat <%= @mat.name %></h3>
|
<h3>Mat <%= @mat.name %></h3>
|
||||||
<h3>Tournament: <%= @mat.tournament.name %></h3>
|
<h3>Tournament: <%= @mat.tournament.name %></h3>
|
||||||
|
|
||||||
<% if @match %>
|
<%= turbo_stream_from @mat %>
|
||||||
<%= render 'matches/matchstats' %>
|
|
||||||
<% else %>
|
|
||||||
<p>No matches assigned to this mat.</p>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
|
<%= turbo_frame_tag dom_id(@mat, :current_match) do %>
|
||||||
|
<%= render "mats/current_match",
|
||||||
|
mat: @mat,
|
||||||
|
match: @match,
|
||||||
|
next_match: @next_match,
|
||||||
|
show_next_bout_button: @show_next_bout_button %>
|
||||||
|
<% end %>
|
||||||
|
|||||||
@@ -34,3 +34,6 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<br>
|
||||||
|
<p>Total matches without byes: <%= @matches.select{|m| m.loser1_name != 'BYE' and m.loser2_name != 'BYE'}.size %></p>
|
||||||
|
<p>Unfinished matches: <%= @matches.select{|m| m.finished != 1 and m.loser1_name != 'BYE' and m.loser2_name != 'BYE'}.size %></p>
|
||||||
68
test/models/match_broadcast_test.rb
Normal file
68
test/models/match_broadcast_test.rb
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class MatchBroadcastTest < ActiveSupport::TestCase
|
||||||
|
include ActionView::RecordIdentifier
|
||||||
|
|
||||||
|
test "broadcasts to old and new mats when mat changes" do
|
||||||
|
create_double_elim_tournament_single_weight_1_6(4)
|
||||||
|
mat1 = @tournament.mats.create!(name: "Mat 1")
|
||||||
|
mat2 = @tournament.mats.create!(name: "Mat 2")
|
||||||
|
@tournament.matches.update_all(mat_id: nil)
|
||||||
|
match = @tournament.matches.first
|
||||||
|
|
||||||
|
# Set an initial mat
|
||||||
|
match.update!(mat: mat1)
|
||||||
|
stream1 = stream_name_for(mat1)
|
||||||
|
stream2 = stream_name_for(mat2)
|
||||||
|
|
||||||
|
# Clear the stream so we can test changes from this state
|
||||||
|
clear_streams(stream1, stream2)
|
||||||
|
|
||||||
|
# Update the mat and check the stream
|
||||||
|
match.update!(mat: mat2)
|
||||||
|
assert_equal [mat1.id, mat2.id], match.saved_change_to_mat_id
|
||||||
|
|
||||||
|
assert_equal 1, broadcasts_for(stream1).size
|
||||||
|
assert_equal 1, broadcasts_for(stream2).size
|
||||||
|
|
||||||
|
assert_includes broadcasts_for(stream2).last, dom_id(mat2, :current_match)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "broadcasts when a match is removed from a mat" do
|
||||||
|
create_double_elim_tournament_single_weight_1_6(4)
|
||||||
|
mat = @tournament.mats.create!(name: "Mat 1")
|
||||||
|
@tournament.matches.update_all(mat_id: nil)
|
||||||
|
match = @tournament.matches.first
|
||||||
|
|
||||||
|
# Set an initial mat
|
||||||
|
match.update!(mat: mat)
|
||||||
|
stream = stream_name_for(mat)
|
||||||
|
|
||||||
|
# Clear the stream so we can test changes from this state
|
||||||
|
clear_streams(stream)
|
||||||
|
|
||||||
|
# Update the mat and check the stream
|
||||||
|
match.update!(mat: nil)
|
||||||
|
assert_equal [mat.id, nil], match.saved_change_to_mat_id
|
||||||
|
|
||||||
|
assert_equal 1, broadcasts_for(stream).size
|
||||||
|
assert_includes broadcasts_for(stream).last, dom_id(mat, :current_match)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def broadcasts_for(stream)
|
||||||
|
ActionCable.server.pubsub.broadcasts(stream)
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear_streams(*streams)
|
||||||
|
ActionCable.server.pubsub.clear
|
||||||
|
streams.each do |stream|
|
||||||
|
broadcasts_for(stream).clear
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def stream_name_for(streamable)
|
||||||
|
Turbo::StreamsChannel.send(:stream_name_from, [streamable])
|
||||||
|
end
|
||||||
|
end
|
||||||
29
test/views/mats_current_match_partial_test.rb
Normal file
29
test/views/mats_current_match_partial_test.rb
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class MatsCurrentMatchPartialTest < ActionView::TestCase
|
||||||
|
include ActionView::RecordIdentifier
|
||||||
|
|
||||||
|
test "renders current match contents when assigned" do
|
||||||
|
create_double_elim_tournament_single_weight_1_6(4)
|
||||||
|
mat = @tournament.mats.create!(name: "Mat 1")
|
||||||
|
match = @tournament.matches.first
|
||||||
|
|
||||||
|
match.update!(mat: mat)
|
||||||
|
|
||||||
|
render partial: "mats/current_match", locals: { mat: mat }
|
||||||
|
|
||||||
|
assert_includes rendered, "Bout"
|
||||||
|
assert_includes rendered, match.bout_number.to_s
|
||||||
|
assert_includes rendered, mat.name
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders friendly message when no matches assigned" do
|
||||||
|
create_double_elim_tournament_single_weight_1_6(4)
|
||||||
|
mat = @tournament.mats.create!(name: "Mat 1")
|
||||||
|
@tournament.matches.update_all(mat_id: nil)
|
||||||
|
|
||||||
|
render partial: "mats/current_match", locals: { mat: mat }
|
||||||
|
|
||||||
|
assert_includes rendered, "No matches assigned to this mat."
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user